I'm having trouble figuring out how to lay out views in Swift Playgrounds for iPad, though this may also be relevant to Mac users.
The following code should create a view with a red square (also a view) that is near the edges of its' super view, but not touching them.
let v = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let sqv = UIView(frame: CGRect(x: 400, y: 400, width: 50, height: 50))
sqv.backgroundColor = .red
v.addSubview(sqv)
PlaygroundPage.current.liveView = v
The result is not what you'd expect:
I suspect I know what is going on here; live views are at a fixed size that is larger than the display area. Some characteristics of the view are ignored when it is acting as the live view. However, I can't find where this is mentioned in the documentation, which vexes me. More importantly, how do I deal with this? I would like to be able to layout simple UIs that change to fit the current size of the live view. I don't know how to address this issue without trial & error and hardcoding, which are two things I would really like to avoid.
I suspect I know what is going on here; live views are at a fixed size that is larger than the display area.
Actually it's more like the other way around. An iPad screen is 1024 points wide (in landscape orientation). The right-hand pane (where it shows your live view) is 512 points wide. The playground forces your root view (v
) to fill that pane, inset by 40 points on the left, right, and top (and more on the bottom). So your root view's width is forced to 432 ( = 512 - 2 * 40), less than the 500 you specified.
Views created in code (like yours) have translatesAutoresizingMaskIntoConstraints = true
, and a resizing mask of 0, which means don't adjust the view's frame at all when its parent is resized. So the playground resizes your root view to width 432, but your root view doesn't move or resize its subview (sqv
).
The easiest fix is to set the autoresizing mask of the subview to express your intent that it remain near the right and bottom edges of the root view. That means it should have flexible top and left margins:
let v = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let sqv = UIView(frame: CGRect(x: 400, y: 400, width: 50, height: 50))
sqv.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin]
sqv.backgroundColor = .red
v.addSubview(sqv)
PlaygroundPage.current.liveView = v
Result:
let sqv = UIView(frame: CGRect(x: UIScreen.mainScreen().bounds.width-50-1, y:400, width: 50, height: 50))
The above code places your subview 1 point away from the right of the main view. Try changing the value 1 after 50 in x to desired value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With