[英]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
}
}
我想做两件事-
编辑文本单元格后得到通知,以便我可以使用“默认值”模块保存更改的数据
通过单击加号添加新数据后,它会添加双击或按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()
转到界面生成器
在视图控制器中,在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.