OSX 开发知识点汇总(五)

栏目: IOS · 发布时间: 6年前

内容简介:在 OSX 中有一些列表的需求,这时候需要使用 OSX 中 TableView 来实现,但是这个 TableView 与 Android的 ListView 不太一样。使用还是比较复杂的。下面做一个简单的介绍,下面为实现上面的方法可以对基本的 TableView 进行渲染处理,可以看到

在 OSX 中有一些列表的需求,这时候需要使用 OSX 中 TableView 来实现,但是这个 TableView 与 Android的 ListView 不太一样。使用还是比较复杂的。下面做一个简单的介绍,

TableView 的使用

  1. 首先需要在布局文件中,拖出一个TableView,并且添加相应的每列的数据源,主要是 使用 TableCellView , 里面默认的控件有一个 TextFiled 和一个 ImageView ,如果需要其他控件则需要自己进行自定义进行实现,下一小节会说到。

  2. 需要对 TableView 设置一个数据源,需要实现 NSTableViewDataSource 接口, 并对 TableView 设置数据源,如下:

    tableView.dataSource = self
    
    extension MainView: NSTableViewDataSource {
        func numberOfRows(in tableView: NSTableView) -> Int {
            return dataSources.count
        }
    }
    
  3. 对每行的数据进行渲染处理,设置 delegatetarget 代理,并实现 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 类中也只有默认 textFiledNSImageView 控件,如果需要在一个 NSTableCellView 中有两个控件,或者有其他的控件如:NSButton等,则目前是无法完成的,那接下来就介绍下 NSTableCellView 的自定义操作。

TableView 中 TableCellView的自定义

  1. 自定义 NSTableCellView ,首先先创建一个 CustomerTableViewCell 类,其继承自 NSTableCellView ,
  2. 其次主要在 xib 或者 storyboard 的 TableViewNSTableCellView 添加新的控件,或者移除掉原来的,添加新的控件进去,并设置相应的约束,与普通 View 操作一致的。最后将自定义的 NSTableCellView 的类名指定为自定义的类名。
  3. 将新添加的控件拖到 CustomerTableViewCell 中连线,这样 CustomerTableViewCell 就可以控制自定义添加的控件了。
  4. 在上面的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 来区分不同的 NSStoryboardSegueidentifier 是在每个每条连线 Segue 上设置,同时记得把类指定为我们定义的类型。

示例如下:

class CustomerStoryboardSegue: NSStoryboardSegue {
    
    override func perform() {
        super.perform()
        // 下面则可以做其他的事情了。通过self.identifier 来区分不同的 Sugue,
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

垃圾回收的算法与实现

垃圾回收的算法与实现

中村成洋、相川光 / 丁灵 / 人民邮电出版社 / 2016-7-1 / 99.00元

★ Ruby之父Matz作推荐语:上古传承的魔法,彻底揭开垃圾回收的秘密! ★ 日本天才程序员兼Lisp黑客竹内郁雄审校 本书前半介绍基本GC算法,包括标记-清除GC、引用计数、复制算法的GC、串行GC的算法、并发GC的算法等。后半介绍V8、Rubinius、Dalvik、CPython等几种具体GC的实现。本书适合各领域程序员阅读。一起来看看 《垃圾回收的算法与实现》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具