内容简介:在 OSX 中有一些列表的需求,这时候需要使用 OSX 中 TableView 来实现,但是这个 TableView 与 Android的 ListView 不太一样。使用还是比较复杂的。下面做一个简单的介绍,下面为实现上面的方法可以对基本的 TableView 进行渲染处理,可以看到
在 OSX 中有一些列表的需求,这时候需要使用 OSX 中 TableView 来实现,但是这个 TableView 与 Android的 ListView 不太一样。使用还是比较复杂的。下面做一个简单的介绍,
TableView 的使用
-
首先需要在布局文件中,拖出一个TableView,并且添加相应的每列的数据源,主要是 使用
TableCellView
, 里面默认的控件有一个TextFiled
和一个ImageView
,如果需要其他控件则需要自己进行自定义进行实现,下一小节会说到。 -
需要对 TableView 设置一个数据源,需要实现
NSTableViewDataSource
接口, 并对TableView
设置数据源,如下:tableView.dataSource = self extension MainView: NSTableViewDataSource { func numberOfRows(in tableView: NSTableView) -> Int { return dataSources.count } }
-
对每行的数据进行渲染处理,设置
delegate
和target
代理,并实现NSTableViewDelegate
接口中如下方法
tableView.delegate = self tableView.target = self
下面为实现 NSTableViewDelegate
接口
extension MainView: NSTableViewDelegate { fileprivate enum CellIdentifiers { static let avatarImgCell = NSUserInterfaceItemIdentifier("image") static let nickNameCell = NSUserInterfaceItemIdentifier("name") } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let item = dataSouece[row] // 图片的资源 var image: NSImage? //名称 var nickName: String = "" var cellIdentifier: NSUserInterfaceItemIdentifier = CellIdentifiers.nickNameCell if tableColumn == tableView.tableColumns[0] { image = #imageLiteral(resourceName: "member_avatar") cellIdentifier = CellIdentifiers.avatarImgCell } else if tableColumn == tableView.tableColumns[1] { nickName = item.nickName cellIdentifier = CellIdentifiers.nickNameCell } // 通过 NSUserInterfaceItemIdentifier 构建每一个 CellView let view = tableView.makeView(withIdentifier: cellIdentifier, owner: nil) if let cellItem = view as? NSTableCellView { // 对 CellView 中默认控件进行设置每个资源 cellItem.textField?.stringValue = nickName cellItem.imageView?.image = image return cellItem } return nil } }
上面的方法可以对基本的 TableView 进行渲染处理,可以看到 NSTableCellView
类中也只有默认 textFiled
与 NSImageView
控件,如果需要在一个 NSTableCellView
中有两个控件,或者有其他的控件如:NSButton等,则目前是无法完成的,那接下来就介绍下 NSTableCellView
的自定义操作。
TableView 中 TableCellView的自定义
-
自定义
NSTableCellView
,首先先创建一个CustomerTableViewCell
类,其继承自NSTableCellView
, -
其次主要在 xib 或者 storyboard 的
TableView
中NSTableCellView
添加新的控件,或者移除掉原来的,添加新的控件进去,并设置相应的约束,与普通 View 操作一致的。最后将自定义的NSTableCellView
的类名指定为自定义的类名。 -
将新添加的控件拖到
CustomerTableViewCell
中连线,这样CustomerTableViewCell
就可以控制自定义添加的控件了。 - 在上面的TableView 回调中设置相应的值。
我们拿上面的例子来改造下,
class CustomerNSTableCellView: NSTableCellView { // 添加了一个 age 的label 在同一个CellView中 @IBOutlet weak var ageLabel: NSTextField! override init(frame frameRect: NSRect) { super.init(frame: frameRect) } required init?(coder: NSCoder) { super.init(coder: coder) } override func awakeFromNib() { super.awakeFromNib() } }
extension MainView: NSTableViewDelegate { func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let item = dataSouece[row] // 图片的资源 var image: NSImage? //名称 var nickName: String = "" var age : Int = 1 var cellIdentifier: NSUserInterfaceItemIdentifier = CellIdentifiers.nickNameCell if tableColumn == tableView.tableColumns[0] { image = #imageLiteral(resourceName: "member_avatar") cellIdentifier = CellIdentifiers.avatarImgCell } else if tableColumn == tableView.tableColumns[1] { nickName = item.nickName age = item.age cellIdentifier = CellIdentifiers.nickNameCell } // 通过 NSUserInterfaceItemIdentifier 构建每一个 CellView let view = tableView.makeView(withIdentifier: cellIdentifier, owner: nil) if let cellItem = view as? NSTableCellView { if cellItem is CustomerNSTableCellView { let userCellItem = cellItem as! CustomerNSTableCellView userCellItem.ageLabel.stringValue = age userCellItem.textField?.stringValue = nickName } else { // 对 CellView 中默认控件进行设置每个资源 cellItem.textField?.stringValue = nickName // 这里默认的Cell里没有则控件会为空。 cellItem.imageView?.image = image } return cellItem } return nil } }
至此可以在每个 NSTableCellView
中进行任意的自定义了,实现自己想要实现的功能。
NSStoryboardSegue 的自定义
NSStoryboardSegue
的功能是什么呢?官方文档是这样介绍的: A transition or containment relationship between two scenes in a storyboard.
也就是在多个 storyboard 或者 window 中进行的连线,这个连线可以定义一些功能,比如说 show
操作等等,比如我们点击一个按钮,打开(show)另外一个 window 则可以使用它进行连线操作后,这条线就是 NSStoryboardSegue
类型的。
那么为什么要自定义它呢? 因为如果在 storyboard 中对某个控件连线使用 NSStoryboardSegue
后,如果在对该控件执行 action
操作时, action
操作会不起作用,这点需要吐槽下苹果的设计了。如果要想再使用 NSStoryboardSegue
后还可以指定其他操作,则只能自定义 NSStoryboardSegue
了。
在自定义中复写 perform()
方法,可以添加自定义的一些操作了。
如果一个项目中有多个需要自定义,可以使用 NSStoryboardSegue
中的 identifier
来区分不同的 NSStoryboardSegue
。 identifier
是在每个每条连线 Segue
上设置,同时记得把类指定为我们定义的类型。
示例如下:
class CustomerStoryboardSegue: NSStoryboardSegue { override func perform() { super.perform() // 下面则可以做其他的事情了。通过self.identifier 来区分不同的 Sugue, } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端知识点汇总
- Java知识点汇总
- OSX 开发知识点汇总(一)
- ES6面试、复习干货知识点汇总(全)
- Android复习资料——Java知识点汇总(一)
- Android复习资料——Android知识点汇总(一)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
垃圾回收的算法与实现
中村成洋、相川光 / 丁灵 / 人民邮电出版社 / 2016-7-1 / 99.00元
★ Ruby之父Matz作推荐语:上古传承的魔法,彻底揭开垃圾回收的秘密! ★ 日本天才程序员兼Lisp黑客竹内郁雄审校 本书前半介绍基本GC算法,包括标记-清除GC、引用计数、复制算法的GC、串行GC的算法、并发GC的算法等。后半介绍V8、Rubinius、Dalvik、CPython等几种具体GC的实现。本书适合各领域程序员阅读。一起来看看 《垃圾回收的算法与实现》 这本书的介绍吧!