我试图了解可可绑定的方向性。特别是,我已经编写了这个小程序来演示绑定,但是我不确定为什么会输出它的作用。这是程序:
@interface SimpleClass : NSObject
@property (retain) NSString *s;
@end
@implementation SimpleClass
@end
int main(int argc, char *argv[]) {
SimpleClass *simpleClass1 = [[SimpleClass alloc] init];
SimpleClass *simpleClass2 = [[SimpleClass alloc] init];
[simpleClass1 bind:@"s" toObject:simpleClass2 withKeyPath:@"s" options:nil];
//[simpleClass1 willChangeValueForKey:@"s"];
simpleClass1.s = @"Hello, World!";
//[simpleClass1 didChangeValueForKey:@"s"];
NSLog(@"%@", simpleClass1.s);
NSLog(@"%@", simpleClass2.s);
simpleClass2.s = @"Something else!";
NSLog(@"%@", simpleClass1.s);
NSLog(@"%@", simpleClass2.s);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行该程序时,输出为:
Hello, World!
(null)
Something else!
Something else!
Run Code Online (Sandbox Code Playgroud)
这使我相信绑定是单向的。不过,我已经遇到这个和这个,这两个似乎是说,绑定应该是双向的(虽然也不是很清楚)。取消注释willChangeValueForKey和didChangeValueForKey行不会影响输出。
我的结论是正确的,绑定是单向的吗?还是有一些方法可以在绑定创建时指定它是双向的?
我正在学习KVC和绑定.目前,我正在尝试将NSTextField绑定到计算属性colorWallStr.我已将滑块的值绑定到相应的颜色变量,并将标签的值绑定到计算属性.
但是,当我移动幻灯片时,标签的内容不会改变.
// Inside MainWindowController
dynamic var colorRed: CGFloat = 1.0
dynamic var colorGreen: CGFloat = 1.0
dynamic var colorBlue: CGFloat = 0.0
dynamic var colorWallStr: String {
get {
return "R: \(colorRed) G: \(colorGreen) B: \(colorBlue)"
}
}
Run Code Online (Sandbox Code Playgroud)
当我将标签直接粘贴到颜色变量时,它工作正常.
谢谢@ vadian的回答.现在我可以使用property didSet更新标签来触发更新标签方法(见下文).
dynamic var colorBlue: CGFloat = 0.0 {
didSet {
updateLabel()
}
}
func updateLabel() {
colorWall = "R: \(colorRed) G: \(colorGreen) B: \(colorBlue)"
}
Run Code Online (Sandbox Code Playgroud)
如果字符串插值中使用的属性不更新封闭的计算属性,那么为什么以下代码片段不起作用?
dynamic var colorWall: String {
get {
let red …Run Code Online (Sandbox Code Playgroud) 我正在 Mac 上开发一个现有的 Swift/Objective-C 项目,并在代码中创建一些 UI。我根据我管理的 NSTableView 中的选择启用一个按钮,而不使用 NSArrayController (出于原因)。
selectionIndexes我在 上拥有房产MyController:
@objc var selectionIndexes : IndexSet = IndexSet()
Run Code Online (Sandbox Code Playgroud)
我不确定是否有@objc必要使其对 Cocoa Bindings 系统可见。
我使用以下方式连接按钮的绑定enabled:
newButton.bind(NSBindingName.enabled, to: MyController.sharedInstance,
withKeyPath: "selectionIndexes",
options: [NSBindingOption.valueTransformer : MyTransformer()])
Run Code Online (Sandbox Code Playgroud)
这工作正常,使用正确的属性调用变压器并正确设置启用,但对选择的更改不会触发绑定,因此按钮保持禁用状态。
我必须明确告诉系统我正在更改该值,例如
self.willChangeValue(for: \.selectionIndexes )
self.selectionIndexes = proposedSelectionIndexes
self.didChangeValue(for: \.selectionIndexes)
Run Code Online (Sandbox Code Playgroud)
这看起来很蹩脚。有更好的方法吗?
我有两个使用绑定链接的核心数据填充的NSTableViews.在NSTableView1中选择行时,将填充NSTableView2并选择其中的第一行.我在其selectionIndex上注册了与NSTableView2对应的NSArrayController和KVO.这样,当在NSTableView2中选择一行时,将运行一个方法.我的问题是,当在NSTableView1中选择一行时,选择NSTableView2中的第一行来触发该方法.我想这样我可以在NSTableView1中选择一行并填充NSTableView2,而无需在NSTableView2中自动选择行.这是如何完成的?
我对可可的绑定世界相当新,我遇到了一些麻烦(可能/可能是由于误解).
我有一个包含一个名为plugins的NSMutableArray的单例,它包含类Plugin的对象.它有一个名为loadPlugins的方法,它将对象添加到插件数组中.这可以在任何时候调用.它已作为Interface Builder中的实例添加.
IB中还有一个NSObjectController,其内容出口连接到单例.还有一个NSArrayController,其contentArray绑定到NSObjectController(控制器键是'选择',模型键路径是'插件',对象类名称是'插件').
最后我有一个包含2列的表视图,其值使用Plugin类中的属性键绑定到NSArrayController的arrangeObjects.
到目前为止如此标准(至少从教程中可以看出).我的麻烦是,当在单例中调用loadPlugins方法,并且对象被添加到plugins数组时,表不会更新以显示对象(除非在加载nib之前调用loadPlugins).在tableView上调用的-reloadData不执行任何操作.
有没有办法告诉NSArrayController引用的数组是否已更新?我知道NSArrayController有-add:方法,可以在loadPlugins中使用,但这是不可取的,因为我想让单例与显示方面完全分开.
这似乎与: Refresh Cocoa-Binding - NSArrayController - ComboBox有关
这条线:"编辑控制器后面的阵列"似乎也可能找出问题所在,但我希望有可能让单身人士不知道控制器.
提前致谢.
\编辑...
根据TechZen的建议,这是绑定:
TableColumn --('arrangedObjects', 'pluginName', Value)--> NSArrayController
NSArrayController --('selection', 'plugins', ContentArray)--> NSObjectController
NSObjectController --(content)--> PluginsManager
Run Code Online (Sandbox Code Playgroud) 我有一个绑定到ArrayController的texfield.控制器键是"选择",因为我从NSTableView中选择项目.但是当表格中没有项目时,文本字段会显示灰色文本"无选择".
如何禁止显示此文本并且只有一个空文本字段?或者我如何将"无选择"文本更改为其他内容?
我的主菜单(MainMenu.xib)中有一个名为"Word Wrap"的NSMenuItem.它的值绑定到我的共享用户默认控制器,也在XIB中实例化.它在选择时还会发送以下操作:
- (IBAction)toggleWordWrap:(id)sender {
NSUserDefaultsController *ctrlr = [NSUserDefaultsController sharedUserDefaultsController];
if ([[[ctrlr values] valueForKey:@"wordWrapIsEnabled"] boolValue]) {
// turn on word wrap
} else {
// turn off word wrap
}
}
Run Code Online (Sandbox Code Playgroud)
在我的app delegate +initialize方法中,我使用默认值填充标准用户默认值:
+ (void)initializeDefaults {
NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], @"wordWrapIsEnabled",
// etc.
nil];
NSUserDefaultsController *ctrlr = [NSUserDefaultsController sharedUserDefaultsController];
[ctrlr setInitialValues:defaults];
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我的NSMenuItem状态与我的用户默认值不同步.以下是发生的事情的时间表:
应用发布:
wordWrapIsEnabled 没有第一次选择Word Wrap:
wordWrapIsEnabled不是(BZZZT WRONG)第二次选择Word Wrap:
wordWrapIsEnabled是(BZZZT …我有一个基于Mac窗口的应用程序使用CoreData和Cocoa绑定将CoreData实体绑定到NSArrayController以在NSCollectionView中显示.
我的控制器(设置为视图文件所有者的视图)上有一个名为managedObjectConext的属性.在awakeFromNib方法中,我尝试将managedObjectContext(MOC)属性设置为:
managedObjectContext = [(MyApplicationAppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];
managedObjectContext = [[NSApp delegate] managedObjectContext];
Run Code Online (Sandbox Code Playgroud)
我还将NSArrayControllers MOC绑定配置为'Files Owner'MOC属性,并将属性绑定配置为我的CoreData实体的绑定.
但是,每次我在它即将进行绑定之前运行应用程序时,我都会收到以下错误消息:
Cocoa如果没有托管对象上下文,则无法执行操作
我已经登录控制台检查MOC是不是nil,我认为它不是因为这是来自MOC对象的NSLog:myMoc = NSManagedObjectContext:0x10052f9c0
我现在完全被难过,并且感到沮丧的是,应该如此简单的事情占用了我的大部分时间!任何帮助将不胜感激.
我在XCode 4.2中的NSTableView有一个非常奇怪的问题.我已将数据源设置为表的委托.我的表有3列,每列都有一个标识符("name","mugshot","lastSeen").我的代表
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
Run Code Online (Sandbox Code Playgroud)
正在调用,但表格单元格中仍然显示默认值"TableViewCell".该方法实现如下:
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSMutableDictionary *villain = [self.villains objectAtIndex:row];
id keyName = [tableColumn identifier];
id objectValue = [villain objectForKey:keyName];
return objectValue;
}
Run Code Online (Sandbox Code Playgroud)
tableColumnIdentifier是正确的.我不知道文本为什么没有显示.
br,马丁
我试图对Cocoa Bindings有一个基本的了解,我想创建一个非常简单的项目.我有一个类Person有变量name的类NSString.以下是我希望工作的方式:
Person类的实例中.Person类)的标签会根据实例的name变量自动更改其值Person.我花了几个小时阅读各种教程和Apple Mac Developer Library,但每个例子都只展示了如何让Cocoa Bindings与表一起工作.当我尝试开发更简单的东西时,我觉得我完全迷失了.我创建了一个基础项目,剩下的唯一事情就是创建所有绑定.我很乐意为我提供所有的联系,希望能给我一个解释.https://www.dropbox.com/sh/6hddfxyitqp6uoc/AACgaRhKBhLo6EXCVN9W6GQua?dl=0 该项目是一个基于文档的应用程序,因为我将开发这种类型在未来的应用程序.
cocoa-bindings ×10
cocoa ×8
objective-c ×6
macos ×2
swift ×2
core-data ×1
nsmenuitem ×1
nstableview ×1
xcode ×1
xcode4.2 ×1