I am trying to understand how NSLayoutAnchor works in Objective-C by converting a simple Swift app to it. The Swift app creates an NSView subclass which sets its layer's background color to a randomly generated color (with an extension to NSColor), then creates two instances of it in AppDelegate (inside application:didFinishLaunchingWithOptions
), then creates the array of constraints, add the two views to the superview, activates the constraints and... that's it.
In my Objective-C version, where I have tried to convert everything, it seems that the two custom NSView subclass instances never get initialised. A step-by-step debugging shows their value to be = nil, and while the app launches, the console says:
-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
From that I deduced something may be wrong with the way I initialised my NSView subclass, but not even with duck-explaining I can find what may be wrong. This is the code in ColorView.m ("RandomColor.h") is the extension to get the randomColor
method:
#import "ColorView.h"
#import "RandomColor.h"
@implementation ColorView
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
self.wantsLayer = YES;
self.layer = [[CALayer alloc] init];
self.layer.backgroundColor = [[[NSColor alloc] randomColor] CGColor];
}
NSLog(@"Color View Initialized");
return self;
}
@end
Here is the extension, if you want to test it, but that doesn't seem to be the problem:
@implementation NSColor (RandomColor)
- (NSColor *)randomColor {
CGFloat r = drand48();
CGFloat g = drand48();
CGFloat b = drand48();
CGFloat alpha = 1.0;
return [NSColor colorWithRed:r green:g blue:b alpha:alpha];
}
@end
In AppDelegate.h
I declared two ColorView
properties called leftView
and rightView
, while in AppDelegate.m
:
@synthesize leftView;
@synthesize rightView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
leftView.translatesAutoresizingMaskIntoConstraints = NO;
rightView.translatesAutoresizingMaskIntoConstraints = NO;
NSView *view = [self.window contentView];
[self.window setBackgroundColor:[NSColor systemMintColor]];
if (view) {
[view addSubview:leftView];
[view addSubview:rightView];
[NSLayoutConstraint activateConstraints:@[
[leftView.topAnchor constraintEqualToAnchor:[view topAnchor]],
[leftView.leftAnchor constraintEqualToAnchor:[view leftAnchor]],
[leftView.rightAnchor constraintEqualToAnchor:[view centerXAnchor]],
[leftView.widthAnchor constraintGreaterThanOrEqualToConstant:150],
[leftView.heightAnchor constraintEqualToConstant:100],
[rightView.centerXAnchor constraintEqualToAnchor:[view centerXAnchor] constant:50],
[rightView.centerYAnchor constraintEqualToAnchor:[view centerYAnchor]],
[rightView.widthAnchor constraintEqualToConstant:100],
[rightView.heightAnchor constraintEqualToConstant:100]
]];
}
}
I also looked at the archived documentation for NSView subclassing, stored here, but most of it was either not compiling or not helping in a meaningful way.
Could you please tell me where I am wrong in this code, or what am I missing?
Please also correct me if the title is not appropriate for the question.
Thank you so much
CodePudding user response:
In the sample code leftView
and rightView
are never allocated.
Adding leftView=[[ColorView alloc]initWithFrame:someRect];
(and similar for rightView
) should make the code work.