表情符号选择器需要最少的实现NSTextInputClient
。例如一个按钮:
class MyButton: NSButton, NSTextInputClient {
override var acceptsFirstResponder: Bool {
get {
return true
}
}
override func becomeFirstResponder() -> Bool {
return true
}
override func resignFirstResponder() -> Bool {
return true
}
func insertText(_ string: Any, replacementRange: NSRange) {
// this method is called when the user selects an emoji
if let string = string as? String {
self.title = string
}
}
func setMarkedText(_ string: Any, selectedRange: NSRange, replacementRange: NSRange) {
}
func unmarkText() {
}
func selectedRange() -> NSRange {
return NSMakeRange(0, 0)
}
func markedRange() -> NSRange {
return NSMakeRange(NSNotFound, 0)
}
func hasMarkedText() -> Bool {
return false
}
func attributedSubstring(forProposedRange range: NSRange, actualRange: NSRangePointer?) -> NSAttributedString? {
return nil
}
func validAttributesForMarkedText() -> [NSAttributedString.Key] {
return []
}
func firstRect(forCharacterRange range: NSRange, actualRange: NSRangePointer?) -> NSRect {
// the emoji picker uses the returned rect to position itself
var rect = self.bounds
rect.origin.x = NSMidX(rect)
rect.size.width = 0
return self.window!.convertToScreen(self.convert(rect, to:nil))
}
func characterIndex(for point: NSPoint) -> Int {
return 0
}
}
NSTextInputClient
需要一个NSTextInputContext
. NSView
返回上下文输入上下文 https://developer.apple.com/documentation/appkit/nsview/1483323-inputcontext如果该类符合NSTextInputClient
unless isEditable
已实施并返回false
。标签不返回NSTextInputContext
,解决方案是覆盖inputContext
:
class MyTextField: NSTextField, NSTextInputClient {
var myInputContext : NSTextInputContext?
override var inputContext: NSTextInputContext? {
get {
if myInputContext == nil {
myInputContext = NSTextInputContext(client:self)
}
return myInputContext
}
}
// and the same methods as the button, set self.stringValue instead of self.title in insertText(_:replacementRange:)
}