15

Everything used to work great until yesterday I updated Xcode to version 8.

If I don't use any constraints, I can see the buttons but when I apply constraint(s) to the buttons they disappear, no matter what or how many constraints (height, vertical spacing, trailing etc...) I apply.

When I tap buttons, they act normal (events are always sent so I assume they are actually located there(?)). I tried changing text color, background color, (even adding a new UIButton) but ended with no luck. I can't see the buttons. When I change the background color of Centered View I can see this change on the app. The weirdest part is when I click Debug View Hierarchy on Xcode to see what is going on, everything looks fine there; I can see all buttons located as I expect.

Constraints Design

Testing the app both on iPhone 5 (iOS 9.3.5) and iPhone 6 (iOS 10).

I am using Swift 2.3, iOS 10 and Xcode 8.

Is this a bug on Xcode 8? How to resolve this issue?

UPDATE:

I just realised same constraint problem occurs on UILabel and UIImageView too. They look fine without constraint but when I add any constraint they disappear.

JustWork
  • 1,944
  • 3
  • 22
  • 34
  • 2
    I had the same issue, in my case it was the "layer.CornerRadius" which made the problem.(I set them based on the Button frame before knowing the frame size.)In Xcode 7 it was ok. – Mike.R Sep 26 '16 at 12:32

7 Answers7

20

Solved this by forcing layout before setting any layout-related properties like clipToBounds etc... The tricky part is where and when to call layoutIfNeeded.

In my case, I have an UIButton with horizontal,top,and height constraints. Apparently on Xcode 8, my button's title went suddenly missing. Then weird enough the title appeared after I removed the height constraint. This behaviour indicates an issue probably within the view's layout cycle. I needed to have the height constraint so removing it wasn't really the solution. So I tried to call layoutIfNeeded prior to setting the constraints but no effect.

I generate this button on viewDidLoad on a controller via an NSObject class which handles it. The solution for me was forcing a layoutIfNeeded before calling the method that setUps the button.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view layoutIfNeeded];
    //editBooking - NSObject class where the button gets configured.
    [_editBooking setUpViews];
}

Related issues: clipsToBounds causes UIImage to not display in iOS10 & XCode 8

Edit:

"I think the (0, 0, 1000, 1000) bound initialization is the new way Xcode instanciates views from IB. Before Xcode8, views were created with their configured size in the xib, then resized according to screen just after. But now, there is no configured size in IB document since the size depends on your device selection (at the bottom of the screen)."

Reference: Since Xcode 8 and iOS10, views are not sized properly on viewDidLayoutSubviews

From Apple release notes:

Sending layoutIfNeeded to a view is not expected to move the view, but in earlier releases, if the view had translatesAutoresizingMaskIntoConstraints set to NO, and if it was being positioned by constraints, layoutIfNeeded would move the view to match the layout engine before sending layout to the subtree. These changes correct this behavior, and the receiver’s position and usually its size won’t be affected by layoutIfNeeded.

Some existing code may be relying on this incorrect behavior that is now corrected. There is no behavior change for binaries linked before iOS 10, but when building on iOS 10 you may need to correct some situations by sending -layoutIfNeeded to a superview of the translatesAutoresizingMaskIntoConstraints view that was the previous receiver, or else positioning and sizing it before (or after, depending on your desired behavior) layoutIfNeeded.

Reference: iOS10 release notes

Community
  • 1
  • 1
Teffi
  • 2,498
  • 4
  • 21
  • 40
  • 1
    Would I have to do this in `-(void)awakeFromNib;` for cells too? Edit: I added `[self.contentView layoutIfNeeded];` to the method of one of my affected tableViewCells, and it solved the problem. Probably best I subclass the cell to prevent this from happening again; at least until Apple publishes a update to XCode8 to solve this. – Jargen89 Sep 21 '16 at 14:34
  • @Jargen89 Not sure if this is a bug or a new norm for Xcode - see edits above. Probably we'll get a fix to reduce the severity of the change but I think Apple is now forcing the use of autolayout through this means. I had to replace most of my frame size reliant views with constraints which solved most of the issues w/o having to force layout. – Teffi Sep 21 '16 at 15:08
  • This saved my day! THX! `self.view.layoutIfNeeded()` in swift – Cherrypig Sep 23 '16 at 17:32
  • Great saved The life and Saved lots of hours !!! was in trouble since last 7 days :( – Premal Khetani Oct 20 '16 at 17:47
4

I just found the solution. Most probably this is a Xcode 8 bug. I also faced this issue.

The solution is to change the Xcode version in the interface builder..

Steps,

  1. Select your .xib file.

  2. Open the Utilities section.

  3. Select "File Inspector"

  4. Under the "Interface Builder Documents" change the Xcode version of "Opens in" to "Xcode 7.x"

I think, this will help you.

MacKa
  • 59
  • 7
  • After i have tried everything without success ,so i tried to change it to Opens in XCode 7 .... an alert advice that the storyboard will be closes and then reopened .. after that , i run the app again and the all the buttons appeared ... furthermore storyboard still show opens in XCode 8... – Luca Rocchi Oct 06 '16 at 13:30
  • This is a better solution than both the accepted answer and the highest voted answer, since it will be forward-compatible with future versions of Xcode 8, in which the bug has been fixed, without having to modify code unnecessarily. – Steve Cotner Oct 24 '16 at 06:35
  • 1
    I found one more workaround. Before you set cornerRadius, set `layoutIfNeeded()` to the view. – MacKa Oct 27 '16 at 06:35
  • @MacKa thanks to your answer buddy .. I had wasted by hour in this stupidness of xcode. – Kunal Gupta Dec 10 '16 at 19:05
2

I was missing the point of setting UIButton class to my custom class. I checked my custom class and have seen that I set corner radius on awakeFromNib() method. I called layoutIfNeeded() before I set corner radius which was the solution in my case.

JustWork
  • 1,944
  • 3
  • 22
  • 34
1

I don't know if it's a bug, but I solved it adding self.layoutIfNeeded() on awakeFromNib() method. Just in case, I'm subclassing UIButton...

BUT, if you don't, you can't solve the same problem adding that line of code (at least, you can't at this Xcode version). Using viewDidLayoutSubviews() doesn't work too...

1

Confirmed this is an issue with XCode 8 currently (As of Oct 19) distributed through App Store. It unnecessarily removes some <rect/> element from the Storyboard/xib files.

None of the layoutIfNeeded workarounds works for me. I ended up to download XCode 8 Beta 3 which fixed this issue.

John Wu
  • 1,015
  • 1
  • 12
  • 21
0

constraints for scrollview should be: top,bottom,leading,trailing

constraint for contentview in scrollview should be: top,bottom,leading,trailing,fixed height and center x(horizontally in container)

Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • 1
    I don't think you paid attention to my question. No matter what constraint I apply, buttons disappear. Even if I apply only "height" constraint, they disappear. – JustWork Sep 15 '16 at 05:35
  • what happen if you apply constraint to scrollview ? does it disappear ? – Ketan Parmar Sep 15 '16 at 05:44
  • No, it does not. "When I change the background color of Centered View I can see this change on the app." On this page, only these buttons unseen, rest of the controls (UIScrollView, UIView) never unseen. They look as expected. – JustWork Sep 15 '16 at 05:47
  • then once try to set constraints that i have mentioned in answer. Then add button and then try to set constraint for buttons! – Ketan Parmar Sep 15 '16 at 05:49
  • It does not work because as I said, no matter what and how many constraints I apply, buttons disappear. – JustWork Sep 15 '16 at 06:24
0

It seems that Xcode 8.1 Beta 2 (8T46g) fixes the 1000x1000 content size problem (and of course, the auto-layout issues inside table/collection view cells). So, what it works in Xcode 7.x it works without problems in Xcode 8.1 Beta 2.