1

I am building an app where I want to completely avoid using Storyboard and Interface Builder in general, so all UI should be specified in code. I am using PureLayout, a nice API for configuring AutoLayout constraints.

However, my issue is that it seems like AutoLayout is disabled when not using Interface Builder. updateViewConstraints, the method where I put the layout according to the recommendation given by the PureLayout author, is not called at all.

Just to give a bit more info about my setup:

  • deleted Main.storyboard and removed the entry from my Info.plist
  • manually setup self.window in AppDelegate.m and added UINavigationController with MainMainController as rootViewController

As mentioned, my main issue is that updateViewConstraints does not get called on MainViewController but the UI elements are all displayed with the frames that I passed to them during initilization.

Note: It seems to me like I just need to enable some flag somewhere to mimic the checkbox from Interface Builder with which you can indicate whether you want to use AutoLayout.

enter image description here

MainViewController.m

@interface MainViewController ()

@property (nonatomic, strong) UIButton *startButton;
@property (nonatomic, assign) BOOL didSetupConstraints;

@end

@implementation MainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.view addSubview:self.startButton];
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

- (UIButton *)startButton
{
    if (!_startButton) {
        UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem];
        CGRect startButtonFrame = CGRectMake(75.0, 75.0, 250.0, 44.0);
        startButton.frame = startButtonFrame;
        [startButton setTitle:@"Start" forState:UIControlStateNormal];
        [startButton setTranslatesAutoresizingMaskIntoConstraints:NO];
        _startButton = startButton;
    }
    return _startButton;
}

- (void)updateViewConstraints
{
    NSLog(@"Update view contraints");
    if (!self.didSetupConstraints) {
        [self.startButton autoCenterInSuperview];
        self.didSetupConstraints = YES;
    }
    [super updateViewConstraints];
}

@end
nburk
  • 22,409
  • 18
  • 87
  • 132
  • 1
    I think this library use `updateConstraints` method for UIView subclasses and `updateViewConstraints` for View Controllers. That may be the issue that you are expecting a different method in View Controller to get execute. – Gandalf Mar 23 '16 at 08:51
  • Is your views laying out as per the constraints you set. Have you set translateAutoresizingMaskIntoConstraints = NO? – Bharat Modi Mar 23 '16 at 08:51
  • @Gandalf: sorry my bad, I was actually referring to `updateViewConstraints` not `updateConstraints`, will update this in my post – nburk Mar 23 '16 at 08:53
  • @BharatModi yes, in `viewDidLoad`, I set: `[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];`. then I just simply try to center a button, with this button I also do `[startButton setTranslatesAutoresizingMaskIntoConstraints:NO];` – nburk Mar 23 '16 at 08:55
  • show some actual code, the library sets the translate value for you when you ask it to apply some constraint – Wain Mar 23 '16 at 09:23
  • @Wain sure, I updated the post with the relevant code. I think the issue might be related to PureLayout then, because I am not setting the constraints manually using Apple's API but rather I install them through the library. Note that I used the same code in an IB based project (with an empty View Controller) and it worked. – nburk Mar 23 '16 at 09:28
  • generally the view controllers view doesn't set itself to not translate the mask, it's the superview / parent controller who decides to do that... Try instead just calling `setNeedsLayout` at the end of `viewDidLoad`. – Wain Mar 23 '16 at 09:34
  • hmm, it doesn't work with `[self.view setNeedsLayout];`. I also added `[self.view layoutIfNeeded];` right after, but this didn't help either. – nburk Mar 23 '16 at 09:38
  • If you are using constraints you should not be using frames ideally. And `translateAutoresizingMaskIntoConstraints` has to be set to `false` before adding it to the subview. – GoodSp33d Mar 23 '16 at 12:52
  • I'm just curious as to why you wouldn't use Interface Builder and Auto Layout. The reason I ask is your frame values are hard coded which means the button will be the same size on an iPhone 4s as it is on an iPhone 6s Plus. I'm not having a go at you i am just curious. – latenitecoder Mar 24 '16 at 17:07

0 Answers0