一个 绑定 定义了一个对象属性——源——与另一个对象属性(即目的地)之间的连接。
这种模式可以简化视图控制器,完全去除胶水代码的需求 - 更新视图自模型或相反的代码。它还可在模型层或视图层强制关系。
Cocoa 使用不同的方法来通知客户端值的变化:KVO、目标-动作、通知和委托。因此,绑定由多个 触发器 组成,其中触发器对其中任何一种方法做出响应。
以下是一个简单绑定的代码示例
// Set up the environment
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
RDPersonViewController *personVC = [storyboard instantiateInitialViewController];
personVC.person = [[Person alloc] initWithName:@"Jimmy"];
personVC.bindings = [[BNDBindings alloc] init];
// Define the source property
BNDProperty *sourceProperty = [[BNDProperty alloc] initWithObject:[personVC person] keyPath:@"name"];
// Define the destination property
BNDProperty *destinationProperty = [[BNDProperty alloc] initWithObject:[personVC textField] keyPath:@"text"];
// Create a bind from the source property to the destination property
BNDBinding *binding = [[BNDBinding alloc] initWithSourceProperty:sourceProperty destinationProperty:destinationProperty];
// Add a trigger to update the binding when KVO notifications are sent for person's name property
BNDTrigger *trigger = [[BNDKVOTrigger alloc] initWithKeyPath:@"name" object:[personVC person] delegate:binding];
[binding addTrigger:trigger];
// Add to the VC
[[personVC bindings] addBinding:binding];
上面的代码摘录不完整,因为没有反向绑定来确保人的名字与文本框的文本相匹配。然而,当 [UITextField name]
被修改时,UITextField 不发送 KVO 通知 - 相反,它发送一个 UITextFieldTextDidChangeNotification
。
触发器可以在收到通知时更新绑定
// Create a binding as normal
BNDBinding *binding = [[BNDBinding alloc] initWithSource:[personVC textField] sourceKeyPath:@"text" destination:[personVC person] destinationKeyPath:@"name"];
// Create a trigger and add it to the binding
BNDTrigger *trigger = [[BNDNotificationTrigger alloc] initWithNotificationCenter:[NSNotificationCenter defaultCenter] notificationName:UITextFieldTextDidChangeNotification sender:[personVC textField] delegate:binding];
[binding addTrigger:trigger];
// Add it to the VC's bindings
[[personVC bindings] addBinding:binding];
当触发器收到 UITextFieldTextDidChangeNotification
时,它将使用新文本更新人的名字。
值通常需要从一种格式转换为另一种格式,特别是当从视图层传递到模型层时。您的用户界面组件可能认识到的数据格式与您的模型不同,例如,用户将数字输入到字符串中,而您的模型接受一个数字。一个 转换器 代替了属性对象,在值传递时进行转换。
------------ --------------- ----------- --------------- ------------
| Property | --> | Transformer | --> | Binding | --> | Transformer | --> | Property |
------------ --------------- ----------- --------------- ------------
转换器可以在值从源检索或分配到目的地时转换值——这无关紧要。在以下示例中,destinationProperty
预先定义为一个对象的属性
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
destinationProperty = [[BNDStringToNumberTransformer alloc] initWithProperty:destinationProperty numberFormatter:formatter];
destinationProperty
可以继续像定义对象属性一样处理。
可以通过用另一个转换器初始化转换器(而不是属性)进行转换器的链式调用,例如
transformer = [[CustomTransformer alloc] initWithProperty:transformer];
目前唯一的内置转换器是 BNLStringToNumberTransformer
。欢迎提出建议和贡献力量。
要将 Bindings 安装到您的项目中,将其添加到您的 Podfile 中:pod 'Bindings', '~> 0.2.0'
。
Copyright (c) 2013 Ryan Davies
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.