1

In my swift app I'm working with inputActivityView, really hard, and my idea is to add a scroll view to this view with 2 subviews and paging enable. Here's what I've done, I think the problem are constraints but I don't know how to solve it.

  lazy var scrollView: UIScrollView = {
        let sv = UIScrollView(frame: self.bounds)
        sv.backgroundColor = .blue
        sv.isPagingEnabled = true
        sv.contentSize = .init(width: 2 * self.frame.width, height: 54)
        return sv
    }()

    override init(frame: CGRect) { // the init of the customInputAccessoryView
        super.init(frame: frame)
        setup()
    }

    override var intrinsicContentSize: CGSize {
        return .zero
    }

    func setup() {
        backgroundColor = .red
        autoresizingMask = .flexibleHeight

        addSubview(scrollView)
        scrollView.fillSuperview()
        scrollView.heightAnchor.constraint(equalToConstant: 54).isActive = true


        firstView = UIView(frame: .init(origin: .zero, size: .init(width: frame.width, height: 54)))
        firstView.frame.origin = .zero
        firstView.backgroundColor = .gray
        firstView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(firstView)

        secondView = UIView(frame: firstView.bounds)
        secondView.frame.origin.x = frame.width
        secondView.backgroundColor = .lightGray
        secondView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(secondView)

        addConstraints()
    }

    private func addConstraints() {
        NSLayoutConstraint.activate([
            firstView.widthAnchor.constraint(equalToConstant: frame.width),
            firstView.heightAnchor.constraint(equalToConstant: 54)
       ])
    }

How can I set the constraints for the subviews, because in this way appear only the first view, and I can't scroll to the second one.

1 Answer 1

1

Yes, you're missing some constraints.

First, no need to instantiate views with UIView(frame: ...) if you are then setting .translatesAutoresizingMaskIntoConstraints = false because the frame you just gave it will be ignored.

Second, if you have your constraints setup correctly, no need to set a scroll view's .contentSize

// don't do this
//sv.contentSize = .init(width: 2 * self.frame.width, height: 54)

Third, when configuring subviews of a scroll view, make sure your constraints define Top / Leading / Bottom / Trailing AND Width and Height.

Here's an edited version of your code to try:

class MyInputAccessoryView: UIView {

    lazy var scrollView: UIScrollView = {
        let sv = UIScrollView()
        sv.backgroundColor = .blue
        sv.isPagingEnabled = true
        // no need for this
        //sv.contentSize = .init(width: 2 * self.frame.width, height: 54)
        return sv
    }()

    var firstView: UIView!
    var secondView: UIView!

    override init(frame: CGRect) { // the init of the customInputAccessoryView
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var intrinsicContentSize: CGSize {
        return .zero
    }

    func setup() {
        backgroundColor = .red
        autoresizingMask = .flexibleHeight

        addSubview(scrollView)
        //scrollView.fillSuperview()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: bottomAnchor),
            scrollView.leadingAnchor.constraint(equalTo: leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
            scrollView.heightAnchor.constraint(equalToConstant: 54),
        ])


        //firstView = UIView(frame: .init(origin: .zero, size: .init(width: frame.width, height: 54)))
        //firstView.frame.origin = .zero
        firstView = UIView()
        firstView.backgroundColor = .gray
        firstView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(firstView)

        //secondView = UIView(frame: firstView.bounds)
        //secondView.frame.origin.x = frame.width
        secondView = UIView()
        secondView.backgroundColor = .lightGray
        secondView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(secondView)

        addConstraints()
    }

    private func addConstraints() {
        NSLayoutConstraint.activate([

            // make both subviews equal width and height to scrollView
            firstView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            firstView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
            secondView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            secondView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),

            // constrain firstView Leading and Top to scrollView contentLayoutGuide Leading and Top
            firstView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            firstView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),

            // constrain secondView Leading to firstView Trailing
            secondView.leadingAnchor.constraint(equalTo: firstView.trailingAnchor),

            // constrain secondView Top / Bottom / Trailing Top to scrollView contentLayoutGuide Top / Bottom / Trailing
            secondView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            secondView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            secondView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),

        ])
    }

}
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much, but unluckily it doesn't work, here's a template of what I've tried:drive.google.com/file/d/1hZJFI2D6qKnsO2MYyyIhwdOKwHwof7gv/view if you have time you really help me
@PaulRock - if you look closely at your code, you made two typos... in addConstraints() you have two lines beginning with scrollView. that should begin with secondView. -- If you copy/paste the exact addConstraints() code from my answer, it works as desired.
Thank you very much, Is there a manual where I can study this?
@PaulRock - well, the "manual" is pretty much "the internet." Start with Apple's docs and then go to google (or your favorite search engine) and search for swift auto-layout tutorial -- then read, experiment, read, experiment, read, experiment, read, experiment ...
Thank you very much DonMag, it was a pleasure to talk to you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.