繁体   English   中英

可可:编辑文本单元格(NSTextField)后得到通知并在Swift 4的NSTableView中添加文本单元格后开始编辑文本单元格吗?

[英]Cocoa: Get Notified after Text Cell (NSTextField) is Edited & Start Editing Text Cell after Adding it in NSTableView in Swift 4?

我在这里使用TableView做了一个简单的演示: https : //github.com/deadcoder0904/TableViewDemo

我已经使用默认模块作为依赖项

我的项目看起来像

追随你的梦想

所有代码都在ViewController.swift ,如下所示-

import Cocoa
import Defaults

extension Defaults.Keys {
    static let dreams = Defaults.Key<Array<String>>("dreams", default: [
        "Hit the gym",
        "Run daily",
        "Become a millionaire",
        "Become a better programmer",
        "Achieve your dreams"
        ])
}

class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {

    @IBOutlet weak var table: NSTableView!
    var dreams = defaults[.dreams]
    var selectedRow:Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        table.dataSource = self
        table.delegate = self
    }

    override var acceptsFirstResponder : Bool {
        return true
    }

    override func keyDown(with theEvent: NSEvent) {
        if theEvent.keyCode == 51 {
            removeDream()
        }
    }

    func tableViewSelectionDidChange(_ notification: Notification) {
        let table = notification.object as! NSTableView
        selectedRow = table.selectedRow
    }

    func numberOfRows(in tableView: NSTableView) -> Int {
        return dreams.count
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let dream = table.makeView(withIdentifier: tableColumn!.identifier, owner: self) as! NSTableCellView
        dream.textField?.stringValue = dreams[row]

        return dream
    }

    @IBAction func addTableRow(_ sender: Any) {
        addNewDream()
    }

    @IBAction func removeTableRow(_ sender: Any) {
        removeDream()
    }

    func addNewDream() {
        dreams.append("Double Click or Press Enter to Add Item")
        table.beginUpdates()
        let last = dreams.count - 1
        table.insertRows(at: IndexSet(integer: last), withAnimation: .effectFade)
        table.scrollRowToVisible(last)
        table.selectRowIndexes([last], byExtendingSelection: false)
        table.endUpdates()
        saveDreams()
    }

    func removeDream() {
        if selectedRow >= dreams.count {
            selectedRow = dreams.count - 1
        }
        if selectedRow != -1 {
            dreams.remove(at: selectedRow)
            table.removeRows(at: IndexSet(integer: selectedRow), withAnimation: .effectFade)
        }
        saveDreams()
    }

    func saveDreams() {
        defaults[.dreams] = dreams
    }
}

我想做两件事-

  1. 编辑文本单元格后得到通知,以便我可以使用“默认值”模块保存更改的数据

  2. 通过单击加号添加新数据后,它会添加双击或按Enter键来添加项目,但我想要的是我想添加一个空字符串,该字符串可以用“”来做,但我也希望它能够集中并且可编辑,因此用户无需双击或按Enter即可开始在其中输入文本。

我还想要Swift 4中的解决方案,而不是Objective-C。 如何实现呢?

使用可可绑定,它非常强大,并且节省了大量样板代码。

简短教程:

编辑:要充分利用KVC,数据源必须是具有dynamic属性的NSObject子类

  • 创建一个简单的Dream类( description属性是可选的)

     class Dream : NSObject { @objc dynamic var name : String init(name : String) { self.name = name } override var description : String { return "Dream " + name } } 
  • 在视图控制器中声明数据源数组

     var dreams = [Dream]() 
  • 并将var selectedRow:Int = 0替换为

     @objc dynamic var selectedIndexes = IndexSet() 
  • 转到界面生成器

    • 选择表格视图,按⌥⌘7转到Bindings Inspector。
      Selection Indexes绑定到View Controller Model关键路径 selectedIndexes
      ⌥⌘6并将dataSource (通过拖放)连接到视图控制器( 在此处输入图片说明 )。

    • 在表格列的Table Cell View中选择文本字段File 1 最简单的方法是在文本字段区域中单击
      ⌥⌘7,然后将Value绑定到Table Cell View Model Key Path objectValue.name

  • 在视图控制器中,在viewDidLoad填充数据源数组(我不知道该框架,因此将其省略),然后重新加载表视图。

     override func viewDidLoad() { super.viewDidLoad() let dreamNames = ["Hit the gym", "Run daily", "Become a millionaire", "Become a better programmer", "Achieve your dreams"] dreams = dreamNames.map{Dream(name: $0)} table.reloadData() } 
  • 删除acceptsFirstResponder

  • 删除tableViewSelectionDidChange
  • 删除tableView:viewFor:row:
  •  func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { return dreams[row] } 
  • addNewDream替换为

     func addNewDream() { let last = dreams.count dreams.append(Dream(name: "Double Click or Press Enter to Add Item")) table.insertRows(at: IndexSet(integer: last), withAnimation: .effectGap) table.scrollRowToVisible(last) table.selectRowIndexes([last], byExtendingSelection: false) saveDreams() } 
  • removeDream()替换为

     func removeDream() { guard let selectedRow = selectedIndexes.first else { return } dreams.remove(at: selectedRow) table.removeRows(at: IndexSet(integer: selectedRow), withAnimation: .effectFade) saveDreams() } 

要在以后编辑文本时保存数组,必须实现委托方法controlTextDidEndEditing(_:)

override func controlTextDidEndEditing(_ obj: Notification) {
    saveDreams()
}

并在Interface Builder中将表视图中文本字段的delegate连接到视图控制器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM