4 ms·
Interface Builder and Auto Layout were both designed for the Mac and have never really fit in on iOS. The best way is honestly just to write code: implement a
by panic 8y ago
Interface Builder and Auto Layout were both designed for the Mac and have never really fit in on iOS. The best way is honestly just to write code: implement a -layoutSubviews method which updates the UI to match your app state, then call -setNeedsLayout whenever the state changes.
- aaaaaaaaaab 8y agoPardon? This might have been true when there was a single screen size on iOS and people could get away with hardcoded “pixel perfect” frames, but that’s just sloppy. That’s how you get half-baked apps that don’t properly support right-to-left languages or accessibility features like dynamic type.
- panic 8y agoI'm not talking about hardcoded layout; the math to position a view a certain distance away from an edge is very easy to write. In fact, it's easier to make dynamic views in code. What if you want some part of your layout to change based on the size of a view (as determined by screen size, dynamic type setting, language and so on)? Do you create two separate XIB files? How do you keep them in sync?
- bunnycorn 8y ago> What if you want some part of your layout to change based on the size of a view (as determined by screen size, dynamic type setting, language and so on)? Do you create two separate XIB files? How do you keep them in sync? IB has the resources to handle exactly that, it's called "vary for traits". If you are doing the math, AutoLayout is precisely made to that for you. Even if you want to not use constants (ex: use the sinus function), you can do just the important part in code and alter the IB constraints's constants. Done.
- deleted 8y ago[deleted]
- panic 8y agoVary for traits doesn't do that, though! "Size of a particular view" isn't a trait, and "value of a single constraint" is different from the layout of the view. Let me give a concrete example. Say you're writing a view to display a photo in a swipeable gallery. You want to position the associated UI elements where there happens to be room around the photo. That is, when the photo is tall, you want the UI to be placed on the side, but when the photo is wide, you'd prefer the UI to go on the bottom. The individual UI elements are mostly the same, but the layout is different for each state. With -layoutSubviews, you can write your two layouts as usual, then use an if statement to switch between them: - (void)layoutSubviews { if (_tallMode) { // ... tall layout ... } else { // ... wide layout ... } } Shared code can be factored out as necessary. Animation can be done with the following pattern: [view layoutIfNeeded]; // -setTallMode: sets the layout needed flag if the value changed [view setTallMode:shouldBeTall]; [UIView animateWithDuration:duration animations:^{ [view layoutIfNeeded]; }]; How would you specify these two states using IB/autolayout? And how would you animate between the states as you swipe between photos?
- bunnycorn 8y agoThat's not what you said in the first post, was it? If I wanted to do that, I would but the buttons with two constraints to the bottom and to the trailing (right), and I would change the constants of those two constraints, it's even easy because it's just swapping the constants of the constraint pair.
- deleted 8y ago[deleted]