在制作自定义 iOS 键盘扩展时,如何创建一个与 Apple 原始退格键具有相同功能的按钮?
When making a custom iOS keyboard extension, how can I create a button that has the same functionality as Apple's original backspace key?
我正在制作一个自定义键盘,它有用于删除文本的删除按钮,其代码是:
func addDelete() {
deleteButton = UIButton.buttonWithType(.System) as UIButton
deleteButton.setTitle(" Delete ", forState: .Normal)
deleteButton.sizeToFit()
deleteButton.setTranslatesAutoresizingMaskIntoConstraints(false)
deleteButton.addTarget(self, action: "didTapDelete", forControlEvents: .TouchUpInside)
deleteButton.layer.cornerRadius = 5
view.addSubview(deleteButton)
var rightSideConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1.0, constant: -10.0)
var topConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: +10.0)
view.addConstraints([rightSideConstraint, topConstraint])
}
func didTapDelete() {
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.deleteBackward()
}
但这很慢,因为我必须点击很多次才能从 textField
.
中删除很多字符
有什么方法可以创建一个我可以连续按下的按钮,它可以像默认的那样快速删除一个字符 iPhone keyBoard backSpace 按钮吗?
我从 HERE 中找到了答案。
在此键盘中,删除按钮具有与我想要的相同的功能。
该按钮的代码是:
private func addDeleteButton() {
deleteButton = KeyButton(frame: CGRectMake(keyWidth * 8.5 + spacing * 9.5, keyHeight * 2.0 + spacing * 3.0 + predictiveTextBoxHeight, keyWidth * 1.5, keyHeight))
deleteButton.setTitle("\u{0000232B}", forState: .Normal)
deleteButton.addTarget(self, action: "deleteButtonPressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(deleteButton)
let deleteButtonLongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressForDeleteButtonWithGestureRecognizer:")
deleteButton.addGestureRecognizer(deleteButtonLongPressGestureRecognizer)
let deleteButtonSwipeLeftGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipeLeftForDeleteButtonWithGestureRecognizer:")
deleteButtonSwipeLeftGestureRecognizer.direction = .Left
deleteButton.addGestureRecognizer(deleteButtonSwipeLeftGestureRecognizer)
}
func deleteButtonPressed(sender: KeyButton) {
switch proxy.documentContextBeforeInput {
case let s where s?.hasSuffix(" ") == true: // Cursor in front of tab, so delete tab.
for i in 0..<4 { // TODO: Update to use tab setting.
proxy.deleteBackward()
}
default:
proxy.deleteBackward()
}
updateSuggestions()
}
func handleLongPressForDeleteButtonWithGestureRecognizer(gestureRecognizer: UILongPressGestureRecognizer) {
switch gestureRecognizer.state {
case .Began:
if deleteButtonTimer == nil {
deleteButtonTimer = NSTimer(timeInterval: 0.1, target: self, selector: "handleDeleteButtonTimerTick:", userInfo: nil, repeats: true)
deleteButtonTimer!.tolerance = 0.01
NSRunLoop.mainRunLoop().addTimer(deleteButtonTimer!, forMode: NSDefaultRunLoopMode)
}
default:
deleteButtonTimer?.invalidate()
deleteButtonTimer = nil
updateSuggestions()
}
}
func handleSwipeLeftForDeleteButtonWithGestureRecognizer(gestureRecognizer: UISwipeGestureRecognizer) {
// TODO: Figure out an implementation that doesn't use bridgeToObjectiveC, in case of funny unicode characters.
if let documentContextBeforeInput = proxy.documentContextBeforeInput as NSString? {
if documentContextBeforeInput.length > 0 {
var charactersToDelete = 0
switch documentContextBeforeInput {
case let s where NSCharacterSet.letterCharacterSet().characterIsMember(s.characterAtIndex(s.length - 1)): // Cursor in front of letter, so delete up to first non-letter character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
case let s where s.hasSuffix(" "): // Cursor in front of whitespace, so delete up to first non-whitespace character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
default: // Just delete last character.
charactersToDelete = 1
}
for i in 0..<charactersToDelete {
proxy.deleteBackward()
}
}
}
updateSuggestions()
}
我正在制作一个自定义键盘,它有用于删除文本的删除按钮,其代码是:
func addDelete() {
deleteButton = UIButton.buttonWithType(.System) as UIButton
deleteButton.setTitle(" Delete ", forState: .Normal)
deleteButton.sizeToFit()
deleteButton.setTranslatesAutoresizingMaskIntoConstraints(false)
deleteButton.addTarget(self, action: "didTapDelete", forControlEvents: .TouchUpInside)
deleteButton.layer.cornerRadius = 5
view.addSubview(deleteButton)
var rightSideConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1.0, constant: -10.0)
var topConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: +10.0)
view.addConstraints([rightSideConstraint, topConstraint])
}
func didTapDelete() {
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.deleteBackward()
}
但这很慢,因为我必须点击很多次才能从 textField
.
有什么方法可以创建一个我可以连续按下的按钮,它可以像默认的那样快速删除一个字符 iPhone keyBoard backSpace 按钮吗?
我从 HERE 中找到了答案。
在此键盘中,删除按钮具有与我想要的相同的功能。
该按钮的代码是:
private func addDeleteButton() {
deleteButton = KeyButton(frame: CGRectMake(keyWidth * 8.5 + spacing * 9.5, keyHeight * 2.0 + spacing * 3.0 + predictiveTextBoxHeight, keyWidth * 1.5, keyHeight))
deleteButton.setTitle("\u{0000232B}", forState: .Normal)
deleteButton.addTarget(self, action: "deleteButtonPressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(deleteButton)
let deleteButtonLongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressForDeleteButtonWithGestureRecognizer:")
deleteButton.addGestureRecognizer(deleteButtonLongPressGestureRecognizer)
let deleteButtonSwipeLeftGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipeLeftForDeleteButtonWithGestureRecognizer:")
deleteButtonSwipeLeftGestureRecognizer.direction = .Left
deleteButton.addGestureRecognizer(deleteButtonSwipeLeftGestureRecognizer)
}
func deleteButtonPressed(sender: KeyButton) {
switch proxy.documentContextBeforeInput {
case let s where s?.hasSuffix(" ") == true: // Cursor in front of tab, so delete tab.
for i in 0..<4 { // TODO: Update to use tab setting.
proxy.deleteBackward()
}
default:
proxy.deleteBackward()
}
updateSuggestions()
}
func handleLongPressForDeleteButtonWithGestureRecognizer(gestureRecognizer: UILongPressGestureRecognizer) {
switch gestureRecognizer.state {
case .Began:
if deleteButtonTimer == nil {
deleteButtonTimer = NSTimer(timeInterval: 0.1, target: self, selector: "handleDeleteButtonTimerTick:", userInfo: nil, repeats: true)
deleteButtonTimer!.tolerance = 0.01
NSRunLoop.mainRunLoop().addTimer(deleteButtonTimer!, forMode: NSDefaultRunLoopMode)
}
default:
deleteButtonTimer?.invalidate()
deleteButtonTimer = nil
updateSuggestions()
}
}
func handleSwipeLeftForDeleteButtonWithGestureRecognizer(gestureRecognizer: UISwipeGestureRecognizer) {
// TODO: Figure out an implementation that doesn't use bridgeToObjectiveC, in case of funny unicode characters.
if let documentContextBeforeInput = proxy.documentContextBeforeInput as NSString? {
if documentContextBeforeInput.length > 0 {
var charactersToDelete = 0
switch documentContextBeforeInput {
case let s where NSCharacterSet.letterCharacterSet().characterIsMember(s.characterAtIndex(s.length - 1)): // Cursor in front of letter, so delete up to first non-letter character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
case let s where s.hasSuffix(" "): // Cursor in front of whitespace, so delete up to first non-whitespace character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
default: // Just delete last character.
charactersToDelete = 1
}
for i in 0..<charactersToDelete {
proxy.deleteBackward()
}
}
}
updateSuggestions()
}