gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 14:14:29 26 4
gpt4 key购买 nike

我在这里使用 TableView 做了一个简单的演示: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 以添加项目,但我想要的是添加空字符串,我可以使用 ""但我也希望它具有焦点并且可以编辑,这样用户就可以开始在其中输入文本,而无需双击或按 Enter 键

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

最佳答案

使用 Cocoa Bindings,它非常强大并且节省了大量样板代码。

简短教程:

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

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

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

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

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

    • 选择 TableView ,按 ⌥⌘7 转到绑定(bind)检查器。
      Selection Indexes 绑定(bind)到 View Controller Model Key Path selectedIndexes
      ⌥⌘6 并将 dataSource(通过拖放)连接到 View Controller (enter image description here)。

    • 在表列的 Table Cell View 中选择文本字段 File 1。最简单的方法是在文本字段区域中⌃⇧单击
      ⌥⌘7 并将 Value 绑定(bind)到 Table Cell View Model Key Path objectValue.name (!)

  • 在 View Controller 中填充 viewDidLoad 中的数据源数组(我不知道该框架,所以我将其省略)并重新加载 TableView 。

    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()
}

并在 Interface Builder 中将 TableView 中文本字段的委托(delegate)连接到 View Controller 。

关于swift - Cocoa:在文本单元格(NSTextField)被编辑后得到通知并在 Swift 4 的 NSTableView 中添加文本单元格后开始编辑文本单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52251945/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com