I'm creating a view controller that has non-trivial rotation behavior. I can't find a way to get all my transformations to occur with only UIViewAutoresizing (I'm doing things like keeping by bottom bar at the same "absolute value" on the screen" while rotating buttons). What's the correct way to handle these type of rotation behaviors? Is there a way to disable auto resizing for a specific view and handle the rotations yourself?
If you set a view's autoresizesSubviews property to NO, that view will not apply autoresizing to its subviews. You can do this in a xib or storyboard by unchecking the “Autoresizes Subviews” checkbox in the attributes inspector.
The correct place to programmatically lay out subviews is in the layoutSubviews method of your custom UIView subclass. Your view will receive the layoutSubviews method whenever its size changes or when its subviews array changes. You will receive it when the view is first being put on the screen, and inside the autorotation animation block.
Related
I have a custom UIView that has a few properties like UIButtons and UITextFields. I am animating these to go left and right using UIView.animate(withDuration: 0.25) {} and am simply changing the constraints in the closure to move the properties to their respective positions. These positions are often outside of the view, because I want them to disappear. Is there someway that I can keep the animations, but once the properties begin cross the boundary of the custom UIView, they disappear instead of showing up outside the UIView?
It would be clearer if you called them subviews.
Anyway, based on your comment, it sounds like you want to set the superview's clipsToBounds to true. Then any portion of a subview that is outside it's superview's bounds will not be visible.
You can set clipsToBounds programmatically, or in the view's Attributes inspector in your xib or storyboard.
I want to hide a non child UIView in a UIView but I don't know how to do it.
To be specific, I have a UITableView. Each UITableViewCell has another view inside it (a wrapper view called wrapperView). The wrapper has some labels set up in IB and some created programmatically. I have created a custom slide mechanism that reveals buttons under the wrapper (like the standard one does).
The labels created programmatically don't exceed wrapper's bounds because it clips the subviews. The problem is with the labels created in IB. They are the subviews of contentView.
How can this be solved? Is there a way for a UIView to clip other views on the same level(not parents nor children)? Or "transfer" the labels to the wrapper view?
It isn't completely clear what you're asking. A view will only clip it's subviews, not views that happen to fall within their frame rectangle but aren't subviews.
If you want to move a view object from one view hierarchy to another you can use addSubview(_:) to do so. That will automatically remove it from it's current parent view. To quote the Apple docs:
Views can have only one superview. If view already has a superview and
that view is not the receiver, this method removes the previous
superview before making the receiver its new superview.
Currently having an issue with using auto-layout and UIScrollView. The issue is when I scroll down on the scroll view, a previous UIView (that should be free roaming, and is animated to various positions) gets set back to its initial location where it is located in Storyboard.
What's the best way to make my single UIView not follow the behavior of auto-layout and let it do whatever it wants to do?
In my XCode project, I have a xib file and the main view resizes for the iPhone 5 (as do its subviews).
I have additional UIViews in this Xib (they're not set as subviews of the main view, though) and these ones don't resize even though I have set the auto sizing properties.
Am I doing something wrong or is there a reason that these additional UIViews aren't resizing?
Thanks.
EDIT: I am adding these views as subviews to a parent view in my viewdidload method. Maybe I should do it in viewWILLload?
Seems I've managed to figure it out! You have to set the frame of the UIViews in viewWillAppear to be whatever size you want and then the subviews will resize.
Luckily, in my case, all my tall narrow views that you can see in the screen grab above, are all going to be the height of the screen, so I can set it there and have the subviews position/resize accordingly.
I have a ViewController with a UIScrollView on it. On this VC I programatically adjust the frame of a UILabel which is inside the scroll view. This is done on viewDidLoad. This UILabel comes from the VC's xib file, it is not created programatically, only its frame changed.
When I transition from this VC to another, then back, the UILabel's frame gets reset to the XIB's state. It's text however is not reset, it stays the same text I set before.
My investigation tells me that this occur on layoutSubviews, as the UILabel's properties are correct on willLayoutSubviews, then reset on didLayoutSubviews when moving back to the VC.
Is this expected behaviour? Is there a reason why the label's text remains but the frame gets reset? Is this because the UIScrollView calls layoutSubviews on its parent view whenever scrolling?
Thanks
I see two problems in your description. First, you said this:
On this VC I programatically adjust the frame of a UILabel which is inside the scroll view. This is done on viewDidLoad.
It is generally a bad idea to modify view frames in viewDidLoad, because the system's layout phase (during which layoutSubviews messages are sent) hasn't happened yet. In viewDidLoad, your view's frame hasn't been adjusted for the current device's screen size and interface orientation yet.
Second, you said that you're using autolayout. The autolayout system sets the frames of views during the layout phase. The layout phase can be triggered by many different events, including (as you've discovered) the appearance and disappearance of views.
In order to make your adjustment to the label's frame “stick”, you need to modify the constraints that control the label's frame. One way to do this is to create an outlet of type NSLayoutConstraint on your view controller for each constraint that you need to modify, and connect these outlets to the constraints in your xib. Then in your view controller's viewWillLayoutSubviews, you can modify the constant property of each constraint as necessary. (Ironically, constant is the only modifiable property of an NSLayoutConstraint.)