簡體   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