swift - Cocoa:在 Swift 4 的 NSTableView 中添加文本单元格(NSTextField)后得到通知并开始编辑文本单元格?
问题描述
我在这里使用 TableView 做了一个简单的演示:https ://github.com/deadcoder0904/TableViewDemo
我已将Defaults模块用作依赖项
我的项目看起来像
所有代码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 的解决方案。如何做到这一点?
解决方案
使用 Cocoa Bindings,它非常强大并且节省了大量的样板代码。
简短教程:
编辑:要充分利用 KVC,数据源必须是具有属性的NSObject
子类dynamic
创建一个简单的类
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 Builderdelegate
中将表格视图中的文本字段连接到视图控制器。
推荐阅读
- sql - Azure SQL 数据库查询性能下降(查询存储的原因?)
- python - 在 Scipy Optimize Minimize() SLSQP 中共享目标和约束计算
- python - Chromedriver 不适用于硒
- c++ - 有没有办法在没有 Visual Studio 的情况下使用 DirectXTex?
- flutter - 在颤振加载中加载更多列表,但用户界面没有改变
- pandas - 如何在熊猫中通过 multiIndex 和前一个值交替值?
- python - 在 pyproject.toml 中指定命令行脚本
- reactjs - 动作创建者中的 getState 函数调用始终返回空数组
- r - 基于分布的数据帧样本
- google-api - 使用 Youtube Data API 将视频上传到 youtube 时达到每日限制