0

I am trying to develop an app with the UI created only programmatically. I want to create a simple view which is a UIScrollView (to be able to scroll the view when the keyboard is appearing) with a containerView (UIView) where we can find a button.

I am using PureLayout to make easier the set up of constraints, swift 4, Xcode 9.2 beta

Below the class of this view

class SimpleView: UIScrollView {

var containerView: UIView!
var signInButton: UIButton!
var signInLabel: UILabel!

var screenSize: CGSize = CGSize.zero

var shouldSetupConstraints = true

override init(frame: CGRect) {
    super.init(frame: frame)

    self.screenSize = frame.size

    self.containerView = UIView(frame: CGRect.zero)
    self.signInButton = UIButton(frame: CGRect.zero)
    self.signInLabel = UILabel(frame: CGRect.zero)

    self.addSubview(self.containerView)

    self.containerView.addSubview(self.signInButton)

    self.signInButton.addSubview(self.signInLabel)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func updateConstraints() {
    if(shouldSetupConstraints) {

        self.layoutSignInButton()
        self.layoutSignInLabel()

        shouldSetupConstraints = false
    }
    super.updateConstraints()


}


private func layoutContainerView() {
    self.containerView.autoPinEdgesToSuperviewEdges()
    self.containerView.backgroundColor = UIColor.yellow
}

private func layoutSignInButton() {
    self.signInButton.autoPinEdge(toSuperviewEdge: .right)
    self.signInButton.autoPinEdge(toSuperviewEdge: .left)
    self.signInButton.autoPinEdge(toSuperviewEdge: .top)
    self.signInButton.autoSetDimension(.height, toSize: 55.0)

    self.signInButton.backgroundColor = UIColor(hex: "#FD9FA2")
}

private func layoutSignInLabel() {
    self.signInLabel.autoPinEdgesToSuperviewEdges()

    self.signInLabel.shadowColor = UIColor(hex: "#9A615E")
    self.signInLabel.shadowOffset = CGSize(width: 0.0, height: 2)
    self.signInLabel.text = NSLocalizedString("SIGN IN", comment: "")
    self.signInLabel.textAlignment = .center
    self.signInLabel.textColor = UIColor.white
    self.signInLabel.font = UIFont.boldSystemFont(ofSize: 15.0)
    self.signInLabel.backgroundColor = UIColor.clear
}

}

Below the code of the UIViewController subclass embedding the previous view

class SignInViewController: UIViewController {

var simpleView: SimpleView!

override func viewDidLoad() {
    super.viewDidLoad()

    self.simpleView = SimpleView(frame: self.view.bounds) // with SimpleView(frame: self.view.frame) has the same behaviour
    self.view.addSubview(self.simpleView)

    self.simpleView.autoPinEdgesToSuperviewEdges()
    self.navigationController?.navigationBar.isHidden = true

}
}

Unfortunatly the result is not the one expected : see below

What am I missing ? Different points are missing: - The position of the button is weird (space between the button and the top / left side of the button partly hidden outside of the screen) - the container view is invisible (backgroundColor = UIColor.yellow has no effect)

Thank you by advance !

//////////////////////////// EDIT ////////////////////////////////

Below a screenshot of the exact same code using a UIView instead of UIScrollView

Class SimpleView: UIView {

enter image description here

PaulM
  • 35
  • 6
  • Is updateConstraints ever called? Also, Is there a reason you're using the beta? – GetSwifty Nov 16 '17 at 18:43
  • updateConstraints is called once at the loading of the view (checked with breakpoints) Concerning the beta, there is no special reason (wanted to keep the 8.3 version so i downloaded the first version I found on https://developer.apple.com/download/ which was the 9.2 beta) – PaulM Nov 16 '17 at 18:47
  • What is actually wrong though? Aside from the button that is in the wrong place, what has this go to do with a scroll view? – brandonscript Nov 16 '17 at 19:03
  • You never set the content size for the scrollview. The earliest point at which you know the view controllers view size is `viewWillLayoutSubviews` – Paulw11 Nov 16 '17 at 19:30
  • @brandonscript I did the exact same view in a regular UIView before realising that i needed a scrollview. The only thing I changed between these two solutions is the scrollview. My main problem is that the frame center of my scrollview is not corresponding to the center of the screen. The easy solution would be to set constraint to balance this shift of position, but I would like to understand where is my mistake. I also supposed that the scrollview is the heart of the problem (maybe not..) coz I had similar problem time to time by using storyboard – PaulM Nov 16 '17 at 19:34

1 Answers1

0

The content of a UIScrollView must also define the .contentSize` of the scroll view.

I don't use PureLayout, so I don't know what the syntax is, but in your layoutContainerView() func, you need to also do:

self.containerView ... set width dimension to SuperviewWdith

That will set the content of containerView to the width of the scroll view, and that should fix the width part.

I assume you will be adding elements to containerView and set their constraints to control the height of it.

DonMag
  • 69,424
  • 5
  • 50
  • 86