代码之家  ›  专栏  ›  技术社区  ›  deadcoder0904

Cocoa:在文本单元格(NSTextField)被编辑后得到通知&在swift4的NSTableView中添加文本单元格后开始编辑它?

  •  0
  • deadcoder0904  · 技术社区  · 6 年前

    https://github.com/deadcoder0904/TableViewDemo

    我用过 Defaults

    我的项目看起来像

    follow your dreams

    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键添加项目 但我想要的是我想要添加空字符串,我可以用“”来做,但我也希望它是集中的,并且是可编辑的,这样用户就可以开始在其中输入文本,而不必这样做 .

    我还需要一个Swift 4¬ Objective-C的解决方案。如何实现这一点?

    1 回复  |  直到 6 年前
        1
  •  1
  •   vadian    6 年前

    使用Cocoa绑定,它非常强大,可以节省大量样板代码。

    简短教程:

    要充分利用KVC,数据源必须是 NSObject 子类 dynamic

    • 创建一个简单的类 Dream (the) 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
        绑定 Selection Indexes View Controller 模型密钥路径 selectedIndexes .
        6 并连接 dataSource enter image description here ) .

      • 选择文本字段 File 1 在里面 Table Cell View 在表列中。最简单的方法是 在文本字段区域中。
        7 并绑定 Value 表格单元格视图 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()
       }
      

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

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

    delegate 将表视图中的文本字段添加到视图控制器。