Since Xcode 8 and iOS10, views are not sized properly on viewDidLayoutSubviews
Now, Interface Builder lets the user change dynamically the size of every view controllers in storyboard, to simulate the size of a certain device.
Before this functionality, the user should set manually each view controller size. So the view controller was saved with a certain size, which was used in initWithCoder
to set the initial frame.
Now, it seems that initWithCoder
do not use the size defined in storyboard, and define a 1000x1000 px size for the viewcontroller view & all its subviews.
This is not a problem, because views should always use either of these layout solutions:
autolayout, and all the constraints will layout correctly your views
autoresizingMask, which will layout each view which doesn't have any constraint attached to (note autolayout and margin constraints are now compatible in the same view \o/ !)
But this is a problem for all layout stuff related to the view layer, like cornerRadius
, since neither autolayout nor autoresizing mask applies to layer properties.
To answer this problem, the common way is to use viewDidLayoutSubviews
if you are in the controller, or layoutSubview
if you are in a view. At this point (don't forget to call their super
relative methods), you are pretty sure that all layout stuff has been done!
Pretty sure? Hum... not totally, I've remarked, and that's why I asked this question, in some cases the view still has its 1000x1000 size on this method. I think there is no answer to my own question. To give the maximum information about it:
1- it happends only when laying out cells! In UITableViewCell
& UICollectionViewCell
subclasses, layoutSubview
won't be called after subviews would be correctly layed out.
2- As @EugenDimboiu remarked (please upvote his answer if useful for you), calling [myView layoutIfNeeded]
on the not-layed out subview will layout it correctly just in time.
- (void)layoutSubviews {
[super layoutSubviews];
NSLog (self.myLabel); // 1000x1000 size
[self.myLabel layoutIfNeeded];
NSLog (self.myLabel); // normal size
}
3- To my opinion, this is definitely a bug. I've submitted it to radar (id 28562874).
PS: I'm not english native, so feel free to edit my post if my grammar should be corrected ;)
PS2: If you have any better solution, feel free not write another answer. I'll move the accepted answer.
iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds
I am not sure if this is a new requirement, but I solved this by adding [self layoutIfNeeded];
before doing any cornerRadius
stuff. So my new custom awakeFromNib
looks like this:
- (void)awakeFromNib {
[super awakeFromNib];
[self layoutIfNeeded];
self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
self.tag2label.clipsToBounds=YES;
}
Now they all appear fine.
clipsToBounds causes UIImage to not display in iOS10 & XCode 8
I had the same problem and calling layoutIfNeeded
before all the rounded corner / clipsToBounds
stuff fixed the issue. iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds
ios10: viewDidLoad frame width/height not initialized correctly
The most common issues you describe are appearing in iOS 10 only and can be solved by adding this line (if necessary):
self.view.layoutIfNeeded()
just above the code, that is responsible for changing constraint, layer.cornerRadius etc.
OR
place your code related to frames / layers into viewDidLayoutSubviews()
method:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.layer.cornerRadius = self.myView.frame.size.width/2
view.clipsToBounds = true
... etc
}
XCode 8: Unable to set Size
Xcode 8. In the bottom left you can see
When is view frame size set in iOS10 SDK?
In iOS 10, I met this issue right after I started to use Xcode 8 in june, when it was beta. This solution is needed:
Put layoutIfNeeded()
right before your layer modifications:
self.view.layoutIfNeeded()
view.layer.cornerRadius = view.frame.size.width / 2
view.clipsToBounds = true
OR
place the code for corner radius to viewDidLayoutSubviews()
method:
override func viewDidLayoutSubviews() {
view.layer.cornerRadius = view.frame.size.width / 2
view.clipsToBounds = true
}
Xcode 8 - Some Views & VCs Not Showing Up on Simulator
So between Xcode 7/Swift 2 --> Xcode 8/Swift 3, something changed with how to turn a UIView into a circle. Here is my code now:
func roundView (_ viewToRound: UIView) {
viewToRound.layer.cornerRadius = 20
//viewToRound.layer.cornerRadius = (viewToRound.frame.width/2)
viewToRound.clipsToBounds = true
}
As you can see, I've replaced my cornerRadius method to be an explicit "20" instead of inferred from the view size. With my previous "frame.width" the views were literally not showing up at all. Now they're back to normal. I don't know what changed but this definitely fixed it.
iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds
I am not sure if this is a new requirement, but I solved this by adding [self layoutIfNeeded];
before doing any cornerRadius
stuff. So my new custom awakeFromNib
looks like this:
- (void)awakeFromNib {
[super awakeFromNib];
[self layoutIfNeeded];
self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
self.tag2label.clipsToBounds=YES;
}
Now they all appear fine.
Related Topics
Handling Push Notifications When App Is Terminated
How to Debug an iOS Extension (.Appex)
How to Get Data from Firebase in Descending Order of Value
Programmatically Scroll a Uiscrollview
What Should Image Sizes Be at @1X, @2X and @3X in Xcode
Implementing Google Custom Search API in iOS
Implement Dark Mode Switch in Swiftui App
How Does Xcode Find Implicit Target Dependencies
Detect iOS Application About to Delete
How to Show a Collectionview Like Facebook Upload Image Using Swift 4
Objective-C Get a Class Property from String
Type 'Any' Has No Subscript Members (Firebase)
Passing Parameters to a Method Called by Nstimer in Swift
How to Create a New Swift Project Without Using Storyboards
Using Custom Font in a Uiwebview