簡體   English   中英

如何在iOS 7下使用藍牙鍵盤支持向上和向下箭頭鍵

[英]How can I support the up and down arrow keys with a Bluetooth keyboard under iOS 7

在iOS 6下,當使用外部藍牙鍵盤和在模擬器中工作時,UITextView遵守向上和向下箭頭鍵。 在iOS 7下,向上和向下箭頭鍵不再執行任何操作,但左右箭頭鍵仍然移動光標。

在iOS 7下,如何在UITextView中支持來自外部鍵盤的向上和向下箭頭鍵?

我不知道在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中修復,箭頭鍵按預期移動光標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM