1

I have this UIViewController:

import UIKit

class ViewController: UIViewController {

    var object: DraggableView?

    override func viewDidLoad() {
        super.viewDidLoad() 
        // Create the object
        object = DraggableView(parent: self)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // Add subview
        object?.setup()
    }
}

And I have this class to add the view in this VC:

import UIKit

class DraggableView {

    var parent: UIViewController!

    let pieceOfViewToShow: CGFloat = 30.0

    init(parent: UIViewController) {
        self.parent = parent
    }

    func setup() {
        let view = UIView(frame: parent.view.frame)
        view.backgroundColor = UIColor.red
        parent.view.addSubview(view)
        view.translatesAutoresizingMaskIntoConstraints = false

        view.leadingAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        view.trailingAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        view.heightAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.heightAnchor).isActive = true

        // I need to show only a piece of the view at bottom, so:
        view.topAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.topAnchor, constant: parent.view.frame.height - pieceOfViewToShow).isActive = true
    }
}

Problem

Everything is correct but when the device rotates it loses the constraint and the added view is lost.

I think the problem is in the next line that is not able to update the correct height [parent.view.frame.height] when the device is rotated.

view.topAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.topAnchor, constant: parent.view.frame.height - pieceOfViewToShow).isActive = true

How could I make to update this constant when rotating? I'm using Swift 3.

1 Answer 1

2

You can try using traitCollectionDidChange callback on the UIView to update the constraint when a rotation changes, for that to work you'll need to make DraggableView a subclass of the UIView:

import UIKit

class DraggableView: UIView {

    var parent: UIViewController!

    let pieceOfViewToShow: CGFloat = 30.0

    // keep the constraint around to have access to it
    var topConstraint: NSLayoutConstraint?

    init(parent: UIViewController) {
        super.init(frame: parent.view.frame)
        self.parent = parent
    }

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

    func setup() {
        self.backgroundColor = UIColor.red
        parent.view.addSubview(self)
        self.translatesAutoresizingMaskIntoConstraints = false

        self.leadingAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        self.trailingAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        self.heightAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.heightAnchor).isActive = true

        // keep a reference to the constraint
        topConstraint = self.topAnchor.constraint(equalTo: parent.view.safeAreaLayoutGuide.topAnchor, constant: parent.view.frame.height - pieceOfViewToShow)
        topConstraint?.isActive = true
    }

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        // update the constraints constant
        topConstraint?.constant = parent.view.frame.height - pieceOfViewToShow
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

@JaredPérez sorry, didn't notice that DraggableView does not subclass from UIView.. just use updated version
I think it's a good option, however in the class DraggableView you can not use the method: func traitCollectionDidChange

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.