如何在iOS 7下使用蓝牙键盘支持向上和向下箭头键

在iOS 6下,当使用外部蓝牙键盘和在模拟器中工作时,UITextView使用向上和向下箭头键。 在iOS 7下,向上和向下箭头键不再执行任何操作,尽pipe左右箭头键仍然移动光标。

如何在UITextView下的iOS 7下从外部键盘上下箭头键?

我不知道是否在iOS 7中省略了向上和向下箭头键支持。这里有一个方法可以恢复约95%的丢失的能力。 请注意,这个UITextView子类还纠正了iOS 7中滚动文本视图导致跳跃的几个问题。 我看到它从一个长文件中途跳到文件末尾。

我在这个实现中遇到的唯一问题是重复键没有处理,所以如果你按住向上或向下箭头键,移动光标的代码仍然只被调用一次。

 #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) @implementation ArrowKeyTextView - (id) initWithFrame: (CGRect) frame { self = [super initWithFrame:frame]; if (self) { // This has nothing to do with support for arrow keys, but it does fix a number of issues with scrolling in iOS 7. if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) self.layoutManager.allowsNonContiguousLayout = NO; } return self; } - (NSArray *) keyCommands { UIKeyCommand *upArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputUpArrow modifierFlags: 0 action: @selector(upArrow:)]; UIKeyCommand *downArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputDownArrow modifierFlags: 0 action: @selector(downArrow:)]; return [[NSArray alloc] initWithObjects: upArrow, downArrow, nil]; } - (void) upArrow: (UIKeyCommand *) keyCommand { UITextRange *range = self.selectedTextRange; if (range != nil) { float lineHeight = self.font.lineHeight; CGRect caret = [self firstRectForRange: range]; if (isinf(caret.origin.y)) { // Work-around for a bug in iOS 7 that returns bogus values when the caret is at the start of a line. range = [self textRangeFromPosition: range.start toPosition: [self positionFromPosition: range.start offset: 1]]; caret = [self firstRectForRange: range]; caret.origin.y = caret.origin.y + lineHeight; } caret.origin.y = caret.origin.y - lineHeight < 0 ? 0 : caret.origin.y - lineHeight; caret.size.width = 1; UITextPosition *position = [self closestPositionToPoint: caret.origin]; self.selectedTextRange = [self textRangeFromPosition: position toPosition: position]; caret = [self firstRectForRange: self.selectedTextRange]; if (isinf(caret.origin.y)) { // Work-around for a bug in iOS 7 that occurs when the range is set to a position past the end of the last character // on a line. NSRange range = {0, 0}; range.location = [self offsetFromPosition: self.beginningOfDocument toPosition: position]; self.selectedRange = range; } } } - (void) downArrow: (UIKeyCommand *) keyCommand { UITextRange *range = self.selectedTextRange; if (range != nil) { float lineHeight = self.font.lineHeight; CGRect caret = [self firstRectForRange: range]; if (isinf(caret.origin.y)) { // Work-around for a bug in iOS 7 that returns bogus values when the caret is at the start of a line. range = [self textRangeFromPosition: range.start toPosition: [self positionFromPosition: range.start offset: 1]]; caret = [self firstRectForRange: range]; caret.origin.y = caret.origin.y + lineHeight; } caret.origin.y = caret.origin.y + lineHeight < 0 ? 0 : caret.origin.y + lineHeight; caret.size.width = 1; UITextPosition *position = [self closestPositionToPoint: caret.origin]; self.selectedTextRange = [self textRangeFromPosition: position toPosition: position]; caret = [self firstRectForRange: self.selectedTextRange]; if (isinf(caret.origin.y)) { // Work-around for a bug in iOS 7 that occurs when the range is set to a position past the end of the last character // on a line. NSRange range = {0, 0}; range.location = [self offsetFromPosition: self.beginningOfDocument toPosition: position]; self.selectedRange = range; } } } @end 

除了downArrow中的这个部分外,这对我有用:

  CGRect caret = [self firstRectForRange: range]; if (isinf(caret.origin.y)) { // Work-around for a bug in iOS 7 that returns bogus values when the caret is at the start of a line. range = [self textRangeFromPosition: range.start toPosition: [self positionFromPosition: range.start offset: 1]]; caret = [self firstRectForRange: range]; caret.origin.y = caret.origin.y + lineHeight; } 

我不得不删除if行:

  CGRect caret = [self firstRectForRange: range]; // Work-around for a bug in iOS 7 that returns bogus values when the caret is at the start of a line. range = [self textRangeFromPosition: range.start toPosition: [self positionFromPosition: range.start offset: 1]]; caret = [self firstRectForRange: range]; caret.origin.y = caret.origin.y + lineHeight; 

它就像一个魅力!

看来问题已经在iOS 7.0.3中解决了,方向键按预期移动了光标。