[译]macOS 开发-值绑定(Cocoa Bindings)(1)

译自raywenderlich, 原标题: Cocoa Bindings on macOS, 作者Andy Pereira
macOS 值绑定, 也就是Cocoa binding, 让你不用浪费时间写那些枯燥的代码. 在使用 MVC 模式时, 它会在控制器中自动连接模型与视图.
Cocoa Bindings的目标就是尽可能少的编写代码, 你实际使用过后就会发现, 真好用!!
在这篇关于教程中, 你将学习编写一个 Mac App, 它使用 iTunes API 在 App Store 搜索iOS App并展示出来.
你会学习使用 Cocoa Binding 来做这些事情:

  • Interface Builder 中设置数据模型和 UI (如label, button)之间的关系
  • 设置某个默认值
  • 应用特定的数据格式, 如货币或日期格式
  • 更改数据结构, 例如: 将值转换为某个颜色

开始吧

虽然门槛很低, 但是在你还是需要先学会如何使用 Auto LayoutInterface Builder.
如果你已经会这两个工具了, 在这里下载我们创建好的基础项目.
编译运行, 你会看到它已经有一个基本的界面了, 但目前为止只是个空壳, 还没有任何数据.


你可以看到有几个写好的 Swift文件

  1. iTunesRequestManager.swift 这个文件里面有一个结构体, 结构体有两个静态方法. 第一个方法将查询发送到iTunes API, 会返回JSON格式搜索结果, 第二个是用于异步下载图片的辅助方法.
  2. iTunesResults.swift, 定义了一个与iTunes的返回数据相匹配的数据模型类.

注意: ** Result类中的所有变量都定义为dynamic. 这是因为绑定依赖于键值编码, 需要Objective-C运行时, 添加dynamic关键字可确保始终可用.
该类继承自
NSObject**, 这也是绑定的要求. 当你将一个变量添加到视图控制器类时, 你就知道为什么了.

使用 ITunes 搜索

首先, 你将通过iTunes API搜索, 并将结果添加到NSArrayController中.
打开 Main.storyboard 并查看 View Controller Scene中的对象. 你需要设置绑定的对象都有一个"(Bind)"标记.

设置 NSArrayController

NSArrayController对象管理NSTableView的内容, 通常采用模型对象数组的形式.

注意: NSArrayController提供的不仅仅是一个简单的数组, 包括管理对象的分节, 排序和过滤.

打开Main.storyboard. 在对象库中找到一个NSArrayController对象, 并将其拖动到文档大纲中的视图控制器场景分组下的对象列表中:


接下来, 打开assistant editor, 确保正在编辑的文件是ViewController.swift. 按住control键, 从 storyboard 中的Array Controller对象拖动到ViewController.swift, 为其添加一个outlet, 命名为searchResultsController:

添加搜索按钮事件

现在, 你可以使用搜索按钮获取搜索结果, 然后添加到searchResultsController里面.
按住control, 从storyboard中的搜索按钮拖动到ViewController.swift创建一个事件处理方法. 选择创建一个Action并将其命名为searchClicked.



为searchClicked 添加以下代码

//1
if (searchTextField.stringValue == "") {
  return
}
//2
guard let resultsNumber = Int(numberResultsComboBox.stringValue) else { return }
//3
iTunesRequestManager.getSearchResults(searchTextField.stringValue,
  results: resultsNumber,
  langString: "en_us") { results, error in
    //4
    let itunesResults = results.map { return Result(dictionary: $0) }
 
    //Deal with rank here later  
 
    //5
    DispatchQueue.main.async {
      //6
      self.searchResultsController.content = itunesResults
      print(self.searchResultsController.content)
  }
}

下面来一行一行分析代码:

  1. 检查文本字段; 如果它是空的, 就不要将该查询发送到iTunes搜索API了.
  2. 获取下拉列表中的值. 这个数字传递用于控制每一页要返回多少个搜索结果. 下拉列表中有一些预设值, 也可以手动输入其他数字, 最多为200
  3. 调用 getSearchResults(_:results:langString:completionHandler:). 传入每页数量和搜索字符串. completionHandler 会返回结果或NSError.
  4. 这一行将 Dictionary 数组转换为 Result 数组.
  5. 在你searchResultsController之前, 需要确保处于主线程. 可以使用DispatchQueue.main.async在主队列执行代码. 虽然目前还没有设置任何绑定, 但如果一旦有了, searchResultsController在当前线程将同步更新NSTableView(和其他相关的UI 控件), 有一点需要记住就是更新 UI 必须在主线程操作.
  6. 最后, 设置 NSArrayController 的 content 属性. NSArrayController有许多不同的方法来添加或删除它管理的对象. 我们每次搜索的时候, 都需要清除以前的数据, 并使用最新查询的结果. 现在, 打印searchResultsController的内容, 看看是否工作正常.
    最后, 添加一个ViewController的扩展:
extension ViewController: NSTextFieldDelegate {
  func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
    if commandSelector == #selector(insertNewline(_:)) {
      searchClicked(searchTextField)
    }
    return false
  }
}

这段代码会让在用户在输入的时候中按回车键调用, 就像你点击了搜索按钮一样.
编译运行, 在搜索栏中输入flappy, 然后按回车键或单击搜索按钮. 你应该在控制台中看到以下内容:


你的第一个绑定

来点干货!
NSArrayController绑定到table view.
打开Main.storyboard并选择标题为"Search Results Table View (Bind)"的table view. 打开Bindings Inspector, 如下图所示.
展开"Table Contents"标题下的"Content"选项. 选中"Bind to"旁边的复选框, 在右侧的下拉框中选择SearchResultsController, Controller Key设置为arrangedObjects


编译运行, 随便搜索一个将你觉得返回大量的结果的关键字. 但是除非你更改了下拉列表中的数字, 否则最多只能看到五个结果, .
得益于数据绑定, NSArrayController 会自动在table
view 中显示内容.

你会看到一堆重复的数据, 因为单元格中的文本字段不知道他们应该读取的数据模型中的哪些属性.

将文本字段绑定到属性

打开Main.storyboard并转到View Controller Scene. 展开table view中的对象, 找到名为Title TextField(Bind)的text field. 选择此对象并打开绑定检查器.
展开"value"选项并绑定到"Table Cell View"对象. Model Key Path设置为objectValue.trackName.
objectValue是 table cell view 上的属性, 其值由NSTableView从绑定数据确定.
在这个示例中, objectValue是对应行的Result模型对象.

trackName
trackName

重复以上操作, 对Publisher TextField(Bind)进行绑定, 绑定到objectValue.artistName.
编译运行, 并重新搜索. 你现在可以看到标题和出版商了:

标题和出版商
标题和出版商

添加排名

可以看到排名列还是空的, 怎么做呢?从iTunes获取的数据模型对象上没有排名. 然而, iTunes搜索结果的顺序是已知的.
只需要一点点代码, 就可以设置排名了
在ViewController的//Deal with rank here later注释下添加以下代码:

.enumerated()
.map({ index, element -> Result in
  element.rank = index + 1
  return element
})

该代码调用enumerated()以获取索引和对象在索引. 然后, 它调用map(:_)为每个对象设置rank值, 并返回一个具有该结果的数组.
现在, 返回Main.storyboard, 选择Rank TextField(Bind)并打开Bindings Inspector. 在" value"部分中, 绑定到"Table Cell View". Controller Key 留空, model Key Path 设置为 objectValue.rank.
编译运行, 现在第一列中将会显示排名:



现在, 你需要将Result用户选择的对象绑定到UI的其余部分.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,125评论 29 470
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,029评论 4 62
  • 很多年前,当我刚刚出社会的时候,看过一本时尚杂志,一篇专题内容,是关于,大龄职业女人,在职业上升期间,也在年龄增长...
    叶公子阅读 481评论 8 6
  • 母乳喂养的益处,我并不是一开始就意识到。甚至在怀着诺诺时,我还曾与部门同事一起争论母乳喂养多长时间比较好。 我清楚...
    醒来么么阅读 654评论 0 0
  • 屋孤四壁白,窗外静入怀。 昂首识天际,乌中一点白。 欲斫月中桂,奈何独徘徊。 月本故乡明,心却任我行。
    心洒长空阅读 243评论 2 4