Re: Alternatives to NSMatrix that uses bindings similar to NSMatrix's bindings
Re: Alternatives to NSMatrix that uses bindings similar to NSMatrix's bindings
- Subject: Re: Alternatives to NSMatrix that uses bindings similar to NSMatrix's bindings
- From: Nivek Research <email@hidden>
- Date: Fri, 08 Apr 2016 11:10:00 -0400
For anyone interested I decided to implement a subclass of NSObjectController. Each NSMatrix object is removed from the NIB and replaced with individual NSRadioButtons. I then add an NSObjectController instance to the NIB for each NSMatrix replaced and set its class to RadioGroupController. I bind each radio button’s “value” binding to the appropriate object controller, setting the “Controller Key” to “selection” and setting the “Model Key Path” to the tag value (e.g., 1, 2, 3, etc.) previously assigned to cells in the NSMatrix. I then bind the object controller’s “Content Object” to the original model object (or its proxy object) and corresponding “Model Key Path” previously used by the NSMatrix’s “selectedTag” binding. This solution requires no modifications to my model objects, does not require adding IBOutlets and does not require subclassing either NSWindowController or NSViewController which I rarely had to do for the windows or views that previously contained the deprecated NSMatrix objects. The only other piece to the puzzle is to propagate the value from the object controller back to the model which is accomplished using code similar to Tom Dalling’s solution <http://www.tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/>. All other bindings such as “enabled” and “hidden” map directly from NSMatrix to the individual NSRadioButtons so there is nothing needed for these except to replicate them for each radio button as needed. For brevity here is the gist of the object controller code I use:
@interface RadioGroupController : NSObjectController
@end
NSString* const kKeyPathPrefix = @"selection.";
@implementation RadioGroupController
- (nullable id) valueForKeyPath:(NSString*) inKeyPath {
if (![inKeyPath hasPrefix:kKeyPathPrefix]) {
return [super valueForKeyPath:inKeyPath];
}
NSUInteger const keyPathLength = inKeyPath.length;
NSUInteger const keyPathPrefixLength = kKeyPathPrefix.length;
if (keyPathLength == keyPathPrefixLength) {
return [super valueForKeyPath:inKeyPath];
}
NSString* const keyPath = [inKeyPath substringWithRange:NSMakeRange(keyPathPrefixLength, keyPathLength - keyPathPrefixLength)];
return @([self.content integerValue] == keyPath.integerValue ? NSOnState : NSOffState);
}
- (void) setValue:(nullable id) inValue forKeyPath:(NSString*) inKeyPath {
if (![inKeyPath hasPrefix:kKeyPathPrefix]) {
return [super setValue:inValue forKeyPath:inKeyPath];
}
NSUInteger const keyPathLength = inKeyPath.length;
NSUInteger const keyPathPrefixLength = kKeyPathPrefix.length;
if (keyPathLength == keyPathPrefixLength) {
return [super setValue:inValue forKeyPath:inKeyPath];
}
if ([inValue integerValue] != NSOnState) {
return;
}
NSString* const keyPath = [inKeyPath substringWithRange:NSMakeRange(keyPathPrefixLength, keyPathLength - keyPathPrefixLength)];
[self propagateValue:self.content = @(keyPath.integerValue) forBinding:NSContentObjectBinding];
}
Thanks everyone for your input,
—kevin
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden