0

Im able to initialize my scrollview and set its contentSize with a background color...everything works fine when thats done but when I utilize the following code to add subviews to the scrollView im unable to see those views...please help?

func setupViews(_ views: [NewView]) {
    var multiplier: CGFloat = 0.0
    let width = frame.size.width
    let height = frame.size.height
    for view in views {
        let newView = NewView()
        addSubview(newView)
        newView.frame = CGRect(x: width * multiplier, y: 0, width: width, height: height)
        newView.backgroundColor = .random()
        newView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        newView.centerXAnchor.constraint(equalTo: centerXAnchor, constant: width * multiplier).isActive = true
        multiplier += 1
    }
    contentSize = CGSize(width: width * multiplier, height: height)
}

I have a commonInit() function in NewView class thats called in both required init & override init , might help so here it is

private func commonInit() {
    translatesAutoresizingMaskIntoConstraints = false
    backgroundColor = UIColor.white

    let labels = [nameLabel, brandLabel, priceLabel]
    var multiplier: CGFloat = 0.0

    for label in labels {
        addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 10.0 * multiplier).isActive = true
        label.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0.0).isActive = true
        multiplier += 1.0
    }

}
Paolo
  • 3,825
  • 4
  • 25
  • 41
Mikael491
  • 3
  • 5
  • If you're going to set the position of the views with autolayout constraints then you also have to use them to set the size. – dan Jul 31 '17 at 20:59

1 Answers1

0

Your problem is that when translatesAutoresizingMaskIntoConstraints is called, methods like .frame or .frame.size are ignored/overriden (depending on when you use them, before or after translatesAutoresizingMaskIntoConstraints). As described by Apple:

Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.

And well described in this post

The reason is that using .frame actually ends up creating autoLayout constraints, which are removed when you set translatesAutoresizingMaskIntoConstraints to false. So you need to decide to either use the set .frame method, or to use only constraints.

What I usually end up doing, for simplicity, is to use .frame on large-scale views (like a UIView that might take up the whole screen AND which needs to be moved around latter on), and to use autolayout programmatically on it's subviews, which might not be animated inside of that larger view.

Also, watch out for calling layout methods more than once, it can override certain things depending on the timing of their calls.

jlmurph
  • 1,050
  • 8
  • 17
  • Very much appreciate your feedback & the link to the other post further explaining ```translatesAutoResizingMaskIntoConstraints``` – Mikael491 Jul 31 '17 at 23:42
  • I ended up rewriting the code and handled the layout with visual constraints instead @murphguy – Mikael491 Jul 31 '17 at 23:45