能否通过Cocoa Bindings基于分段控件值切换文本框显示的选中行字段?
我之前做过类似的需求,全程靠绑定和一点点轻量的Value Transformer代码就能搞定,比写IBAction清爽多了。下面是具体步骤:
1. 确认模型与数组控制器的基础绑定
首先假设你的数组控制器已经正确绑定了数据源,表格也已经和数组控制器关联好(选中行时数组控制器的selection会对应到模型对象),模型类有两个字符串属性,比如primaryString和secondaryString,且这两个属性是KVO兼容的(用@property声明即可)。
2. 给分段控件绑定选中状态
先找个合适的控制器类(比如窗口控制器或者App Delegate),添加一个属性来保存分段控件的选中索引:
@property (assign, nonatomic) NSInteger activeStringIndex;
(Swift的话就是@Published var activeStringIndex = 0,记得加@objc让IB能识别)
然后在Interface Builder里选中分段控件,打开Bindings面板:
- 绑定
Selected Index到你刚才创建的activeStringIndex属性,勾选Continuously Updates Value,这样切换分段时会实时更新属性值。
3. 写一个简单的Value Transformer
这个转换器的作用是把「选中的模型对象」和「分段控件索引」结合起来,返回对应的字符串。创建一个继承自NSValueTransformer的类,比如StringSwitcherTransformer:
#import <Cocoa/Cocoa.h> @interface StringSwitcherTransformer : NSValueTransformer @end @implementation StringSwitcherTransformer + (Class)transformedValueClass { return NSString.class; } + (BOOL)allowsReverseTransformation { return NO; } - (id)transformedValue:(id)value { // 这里的value是一个数组,包含两个元素:模型对象、分段索引 if (![value isKindOfClass:NSArray.class] || value.count != 2) { return @""; } id selectedModel = value[0]; NSInteger index = [value[1] integerValue]; return index == 0 ? [selectedModel valueForKey:@"primaryString"] : [selectedModel valueForKey:@"secondaryString"]; } @end
4. 给文本框绑定动态值
回到IB选中文本框,打开Bindings面板:
- 绑定
Value到Multiple Values(多重绑定):- 第一个绑定项:绑定到数组控制器的
selection属性(对应当前选中的模型) - 第二个绑定项:绑定到控制器类的
activeStringIndex属性
- 第一个绑定项:绑定到数组控制器的
- 在绑定的
Value Transformer下拉菜单里,选择你刚才创建的StringSwitcherTransformer
这样就全部搞定了!当你切换分段控件时,activeStringIndex会更新,触发文本框的绑定重新计算,转换器会根据新的索引返回对应的字符串,文本框内容自动切换,全程不需要写任何IBAction或者手动更新UI的代码。
小技巧
如果你的分段控件只有两个选项,也可以把activeStringIndex换成布尔属性(比如showPrimaryString),这样转换器的逻辑会更简单,直接判断布尔值返回对应字符串就行。
内容的提问来源于stack exchange,提问作者Zac

