Wayne Huang Wayne Huang - 3 months ago 6
Swift Question

iOS UIScrollView's width is different from the width set in constraint

I'm new to

iOS
auto layout. I want to implement a view pager using
UIScrollView
with paging enabled. I set the scrollView to (w, h) to (200, 65), but the width of scrollView is always 240 at runtime. As the result, the offset of contents, the label I added into the scrollView, do not match to the scrollView's width. Why are they different? How do I get the right width?

enter image description here
enter image description here

private let contents = ["This is the 1st message",
"This is the 2nd message",
"This is the 3rd message"]

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
super.viewDidLoad()

print("scrollView.bounds = \(scrollView.bounds)")
print("scrollView.frame = \(scrollView.frame)")

var x: CGFloat = 0
for content in contents {
let label = UILabel(frame: CGRectMake(x, 0, 0, 0))
label.text = content
label.sizeToFit()
print("label.frame = \(label.frame)")
scrollView.addSubview(label)
x += scrollView.bounds.width
}

scrollView.contentSize = CGSizeMake(x, scrollView.bounds.height)
}

Output:
scrollView.bounds = (0.0, 0.0, 240.0, 128.0)
scrollView.frame = (80.0, 156.0, 240.0, 128.0)
label.frame = (0.0, 0.0, 178.0, 20.3333333333333)
label.frame = (240.0, 0.0, 185.666666666667, 20.3333333333333)
label.frame = (480.0, 0.0, 182.333333333333, 20.3333333333333)

Answer

Your problem here is that you are using a size class wCompact hRegular for this constraints, so if you have another size class (for example different orientations) you don't have these constraints available.

To set the constraints just for iPhone I suggest doing it programmatically:

if (IDevice.currentDevice().userInterfaceIdiom == .Phone) {
    // Set constraints or a different UIVIew here 
}

And if you have your app available for iPhone Only you can use the class size Any-Any avoiding the programmatically set.