Lucas van Dongen
Lucas van Dongen

Reputation: 9878

Autolayout on custom UIButton does not work on some devices

I am working on an app that has a pause button that is sized with autolayouts. This sometimes leads to the correct size of the rect being called in drawRect and sometimes it's {{0.0},{22,22}} (never something else) leading to a very small Pause Button.

- (void)drawRect:(CGRect)rect
{
    NSLog(@"%@", NSStringFromCGRect(rect));
    // Everything here follows the size of the rect to draw
}

The 22px seems kind of random as that value doesn't appear anywhere in the application. The only thing it reminds me of is that I use a 10px inset for the stuff I draw inside the drawRect (just setting x and y coords, width and height, nothing else on the UIButton) so 42px - 2 * 10px would be 22px.

I set the constraints up in IB as following:

Overview of layouts applied in Interface builder

The following emulators (Xcode 5.1.1) / hardware devices work because they gives me scaled output or do not work when the output is 22px:

The button is 42px in IB.

These are the constraints when it's OK:

po ((UIView*)self.pauseButton).constraints
<__NSArrayM 0x972e160>(
<NSLayoutConstraint:0x979ca10 V:[PauseButton:0x979c6d0(63)]>,
<NSLayoutConstraint:0x979ca40 H:[PauseButton:0x979c6d0(63)]>,
<NSContentSizeLayoutConstraint:0x961f4a0 H:[PauseButton:0x979c6d0(30)] Hug:250 CompressionResistance:750>,
<NSContentSizeLayoutConstraint:0x961f5f0 V:[PauseButton:0x979c6d0(33)] Hug:250 CompressionResistance:750>

Same point when layout fails (this often throws really weird errors instead):

po [self.pauseButton constraints]
<__NSArrayM 0x7f59920>(
<NSLayoutConstraint:0x7f6f980 V:[PauseButton:0x7f6f720(22)]>,
<NSLayoutConstraint:0x7f6f9c0 H:[PauseButton:0x7f6f720(22)]>,
<NSContentSizeLayoutConstraint:0x7f6f360 V:[PauseButton:0x7f6f720(22)] Hug:250 CompressionResistance:750>
)

po [[UIWindow keyWindow] _autolayoutTrace] is the same for both, something similar to an empty VC where you get AMBIGUOUS LAYOUT on the Window and two LayoutGuides:

*<UIWindow:0x108f537f0> - AMBIGUOUS LAYOUT
|   *<UIView:0x109409850>
|   |   *<_UILayoutGuide:0x109409c10> - AMBIGUOUS LAYOUT
|   |   *<_UILayoutGuide:0x10940a540> - AMBIGUOUS LAYOUT

The rest is OK.

I have no idea where the magic 22px constraint comes from or why it only appears in some circumstances.

Upvotes: 1

Views: 1281

Answers (2)

Lucas van Dongen
Lucas van Dongen

Reputation: 9878

I just fixed it by taking the following steps:

  • Removing the PauseButton completely from Interface Builder
  • Adding it again with exactly the same settings
  • Removing the app from the device I was testing on

The part that concerns me most now is that when I did not remove the app from the device, even when I ran it with the PauseButton already completely removed from IB but still having an IBOutlet on my ViewController it would still show the 22px constraints like it was still there.

Only after adding it again and deleting the app from the device it gave up on these phantom constraints.

Upvotes: 1

InkGolem
InkGolem

Reputation: 2762

My guess is that because you've only set the aspect ratio, and not a height, width, trailing, or bottom constraint; its sizing the button to fit its content while still respecting the aspect ratio. Try changing the buttons title or image, or adding additional constraints to so see if it sizes more appropriately.

Upvotes: 0

Related Questions