Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSView layout method not called after setNeedsLayout:YES

As of OSX 10.7 if you wish to perform a manual layout of a NSView you should do so by overriding the layout method and whenever you wish to schedule a call to this method you simply do:

[myView setNeedsLayout:YES] 

I am very familiar with this pattern in iOS however on OSX it does not seem to work. I have created a custom NSView and implemented layout but it seems that it never gets called. Ever. Not after adding subviews, not after calling setNeedsLayout:YES, not ever and I don't know why. I can manually call layout and things work as expected but the docs say never to do this.

From Xcode:

- (void)layout
Override this method if your custom view needs to perform custom
layout not expressible using the constraint-based layout system. In
this case you are responsible for calling setNeedsLayout: when
something that impacts your custom layout changes.

From the online docs:

You should only override layout only if you want to do custom layout. If you do, then you also need to invoke setNeedsLayout: when something that feeds into your custom layout changes.

Link: http://developer.apple.com/library/mac/#releasenotes/UserExperience/RNAutomaticLayout/#//apple_ref/doc/uid/TP40010631-CH1-SW14

Any help is much appreciated.

UPDATE: Here is a link to a sample Xcode project that illustrates the problem LayoutTest.zip

like image 610
nrj Avatar asked Nov 03 '22 20:11

nrj


1 Answers

You need to enable autolayout. If you're using a xib file (and you should be, no commando!) you can check the autolayout checkbox in the Interface Builder Document part of the file inspector.

In code: [myView setTranslatesAutoresizingMaskIntoConstraints:YES]

In your sample project, you have no constraints. The view won't call layout without any constraints.

NSView *aView = self.window.contentView;
NSDictionary *viewsDictionary=NSDictionaryOfVariableBindings(aView, complexView);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[aView]-[complexView]" options:0 metrics:nil views:viewsDictionary];

for (NSLayoutConstraint *constraint in constraints) {
    [complexView addConstraint:constraint];
}
like image 77
Derek Avatar answered Nov 08 '22 06:11

Derek