Jay*_*Jay 9 cocoa nstextfield nspopover swift
此应用程序的目的是确保用户在NSTextField中输入了某个文本.如果该文本不在该字段中,则不应允许它们离开该字段.
给定一个带有子类文本字段的macOS应用程序,一个按钮和另一个通用的NSTextField.单击该按钮时,将显示一个"附加"到字段的NSPopover,该字段由名为myPopoverVC的NSViewController控制.
例如,用户在顶部字段中输入3,然后单击显示弹出窗口的"显示弹出窗口"按钮并提供提示:"1 + 1等于什么".
请注意,此popover有一个标记为1st resp的字段,因此当弹出窗口显示时,该字段将成为第一个响应者.此时不会输入任何内容 - 这只是针对这个问题.
用户可以单击"关闭"按钮,关闭弹出窗口.此时,如果用户点击或标记离开字段中的"3",应该会发生什么,应用程序不应允许该移动 - 可能会发出蜂鸣声或其他消息.但是当弹出窗口关闭并且用户按Tab键时会发生什么
即使其中带有"3"的字段有一个焦点环,它应该在该窗口中再次指示第一个响应者,但是由于未调用textShouldEndEditing函数,用户可以单击或标记它.在这种情况下,我点击了弹出窗口中的关闭按钮,'3'字段有一个聚焦环,我点击了tab,然后进入下一个字段.
这是子文本字段中的函数,在文本输入字段后可以正常工作.在这种情况下,如果用户键入3然后点击Tab,则光标停留在该字段中.
override func textShouldEndEditing(_ textObject: NSText) -> Bool {
if self.aboutToShowPopover == true {
return true
}
if let editor = self.currentEditor() { //or use the textObject
let s = editor.string
if s == "2" {
return true
}
return false
}
Run Code Online (Sandbox Code Playgroud)
showPopover按钮代码将aboutToShowPopover标志设置为true,这将允许子类显示弹出窗口.(当弹出窗口关闭时设置为false)
所以问题是当popover关闭如何将firstResponder状态返回到原始文本字段时?它似乎具有第一响应者状态,并且它认为它具有该状态,尽管未调用textShouldEndEditing.如果你在字段中键入另一个字符,那么一切都按预期工作.就好像窗口的字段编辑器和其中包含"3"的字段一样,因此字段编辑器不会将调用传递给该字段.
该按钮调用一个包含以下内容的函数:
let contentSize = myPopoverVC.view.frame
theTextField.aboutToShowPopover = true
parentVC.present(myPopoverVC, asPopoverRelativeTo: contentSize, of: theTextField, preferredEdge: NSRectEdge.maxY, behavior: NSPopover.Behavior.applicationDefined)
NSApplication.shared.activate(ignoringOtherApps: true)
Run Code Online (Sandbox Code Playgroud)
NSPopover关闭了
parentVC.dismiss(myPopoverVC)
Run Code Online (Sandbox Code Playgroud)
另一条信息.我将这段代码添加到子类NSTextField控件中.
override func becomeFirstResponder() -> Bool {
let e = self.currentEditor()
print(e)
return super.becomeFirstResponder()
}
Run Code Online (Sandbox Code Playgroud)
当弹出窗口关闭并且textField成为Windows第一响应者时,该代码执行但是打印为nil.这表明虽然它是第一个响应者,但它与窗口fieldEditor没有连接,也不会接收事件.为什么?
如果有任何不清楚的地方,请询问.
这是我在如何以编程方式开始 NSTextField 中的文本编辑会话的帮助下进行的尝试?以及如何使我的 NSTextField 在应用程序启动时不突出显示其文本?:
所选范围保存在 中textShouldEndEditing并在 中恢复becomeFirstResponder。insertText(_:replacementRange:)启动编辑会话。
var savedSelectedRanges: [NSValue]?
override func becomeFirstResponder() -> Bool {
if super.becomeFirstResponder() {
if self.aboutToShowPopover {
if let ranges = self.savedSelectedRanges {
if let fieldEditor = self.currentEditor() as? NSTextView {
fieldEditor.insertText("", replacementRange: NSRange(location: 0, length:0))
fieldEditor.selectedRanges = ranges
}
}
}
return true
}
return false
}
override func textShouldEndEditing(_ textObject: NSText) -> Bool {
if super.textShouldEndEditing(textObject) {
if self.aboutToShowPopover {
let fieldEditor = textObject as! NSTextView
self.savedSelectedRanges = fieldEditor.selectedRanges
return true
}
let s = textObject.string
if s == "2" {
return true
}
}
return false
}
Run Code Online (Sandbox Code Playgroud)
也许重命名aboutToShowPopover。
| 归档时间: |
|
| 查看次数: |
351 次 |
| 最近记录: |