Xcode 8 sets the frame size differently. How can I find more information?

In several places in my application, I get frame sizes of zero where I used to get the frame. This especially influenced the creation of round objects by making cornerRadius size/2 .

For example, in Xcode 7, this worked fine:

 class AvatarUIButton: UIButton { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) layer.masksToBounds = true layer.cornerRadius = bounds.size.width / 2 } } 

But now in Xcode 8 I have to do this:

 class AvatarUIButton: UIButton { override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }} required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.layer.masksToBounds = true } } 

In this example, the change is probably better / more obvious. I have another situation that is much less isolated using frame 0 on a TableHeaderView, which is only for xcode 8.

I am looking for release notes, a discussion of a mailing list or the like that discusses a change in the ordering of frame size determination, so I can find out what has changed and how I can fix it.

+6
source share
3 answers

In Xcode 8, Apple says:

Xcode 8 removes the ability to customize views without restrictions with a frame that resizes. Unlimited views may look different after compiling with Xcode 8 when switching size classes at runtime. Go ahead, use constraints and autoresist masks using the device panel to achieve your desired location. (25894544)

In previous versions of Xcode, we used the definition in ViewDidLoad. But here, different elements were not created (and restrictions too), so the view was created with the size in the storyboard.

Now, in Xcode 8, we can no longer do this. We need restrictions because the frame is not initialized (why some of you have these values โ€‹โ€‹for the frame size: 0, 0, 1000, 1000). For example, do it in ViewDidAppear and it will work fine. But first you will see your button without an angular radius.

So you can use this function (here in Objective-C) (where you want, even in the load function):

 [self performSelector:@selector(setCornerToMyButton) withObject:NULL afterDelay:0]; 

You can request a delay, but even with 0 it works.

And change the radius in this function, for example:

 - (void) setCornerToMyButton { //Do what you want... layer.masksToBounds = true layer.cornerRadius = bounds.size.width / 2 } 

Hope this helps you.

+2
source

in your case just call:

 override func draw(_ rect: CGRect) { self.layoutIfNeeded() layer.masksToBounds = true layer.cornerRadius = bounds.size.width / 2 } 

for UIViewController just call view.layoutIfNeed () right after super.viewDidLoad (), it will work like a charm; I donโ€™t know what is the cause of this problem (if itโ€™s a problem) in any case it seems that loading the view is no longer a โ€œlayoutโ€ in the view without using automatic or automatic auto-tuning, as I said that for now you can use this solution. until you get a better idea of โ€‹โ€‹what exactly has changed for custom classes (for example, a custom button), you can override layoutSubviews () or layoutIfNeeded (), there you will find the frame / layout you need and apply any changes you want

+2
source

I got an answer just now.

 [super viewDidLoad]; [self.myNeedFrameView layoutIfNeeded]; 
0
source

All Articles