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,
    }
}

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

查看所有标签

猜你喜欢:

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

新零售新市场

新零售新市场

吴宇 / 人民邮电 / 2017-8

本书全面而实操地解析汽车后市场,帮助诸多正在或将要转型的企业科学转型,在竞争激烈的市场中赢得一席之地,真正实现“互联网+”的飞跃与升级。本书适合汽车后市场相关领域从业者、汽车后市场创业者,以及对汽车后市场有兴趣的读者阅读。一起来看看 《新零售新市场》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器