Курсор вне UITextView

Я искал высоко и низко и не могу найти ответ. Самое близкое, что я видел, это здесь: курсор UITextView ниже фрейма при смене фрейма

Извините, нет скриншотов, так как у меня (почти) нет репутации, но это похоже на связанный пост SO.

Когда я запускаю приложение на iOS6, все работает отлично (контент прокручивается курсором, чтобы держать его на экране), но на iOS7 курсор выходит на одну строку за конец UITextView. Я пытался добавить UIEdgeInsets для перемещения контента, но когда пользователь активно вводит текст, он просто продолжает добавлять новую строку, пока курсор не окажется ниже конца текстового представления.

Мой макет состоит из метки (headerText) с UITextView (textView) под ним. Это представление отображается из панели вкладок. Добавлен аксессуар для ввода с клавиатуры, но его высота вычисляется в высоту клавиатуры автоматически перед вызовом функции.

Вот функция, которую я использую, чтобы изменить размеры моих представлений, вызываемая из клавиатуры, показать / скрыть делегат, повернуть, исходный макет и т. Д.:

-(void)resizeViewsWithKbdHeight:(float)kbHeight
{
    //set the header label frame

    //set constraints
    //total view width - 30 (15 each for left and right padding)
    CGFloat labelWidth = ([[[self navigationController] view] bounds].size.width - 30);
    CGSize constraintSize = {labelWidth, CGFLOAT_MAX};
    //calculate needed height for header label
    CGSize textSize = [[self headerText] sizeWithFont:[UIFont systemFontOfSize:17.0f]
                                    constrainedToSize:constraintSize
                                        lineBreakMode:NSLineBreakByWordWrapping];
    //build and set frame for header label:
    //make it the same as the old
    CGRect headerTempSize = [[self headerLabel] frame];
    //except for the height
    headerTempSize.size.height = textSize.height;
    //and set it
    [[self headerLabel] setFrame:headerTempSize];

    //correct the placement of the UITextView, so it's under the header label

    //build a new frame based on current textview frame
    CGRect newFrame = [[self textView] frame];

    //get the y position of the uitextview, the +8 is the padding between header and uitextview
    CGFloat vertPadding = [[self headerLabel] frame].origin.y + [[self headerLabel] frame].size.height + 8;

    //bump it down vertically
    newFrame.origin.y = vertPadding;

    //bump things down by the amount of the navigation bar and status bar
    float offscreenBump = [[[self navigationController] navigationBar] frame].origin.y + [[[self navigationController] navigationBar] frame].size.height;

    //if we aren't showing the keyboard, add the height of the tab bar
    if(kbHeight == 0) {
        offscreenBump += [[[self tabBarController] tabBar] frame].size.height;
    }

    //calculate the new height of the textview, the +9 is for padding below the text view
    CGFloat newHeight = [[[self navigationController] view] bounds].size.height - ([[self textView] frame].origin.y + 9 + kbHeight + offscreenBump);

    //resize the height as calculated
    newFrame.size.height = newHeight;

    //set textview frame to this new frame
    [[self textView] setFrame:newFrame];
}

Я пытаюсь поддерживать iOS5, поэтому нет AutoLayout.

Возможно, я невероятно наивен в том, что я делаю.

Заранее спасибо!

2 ответа

Решение

Похоже, что это ошибка в iOS 7. Единственный способ, как я нашел, чтобы исправить эту проблему, это добавить делегата для UITextView и реализовать textViewDidChangeSelection, сбросив представление, чтобы показать выбор следующим образом:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

- (void) textViewDidChangeSelection: (UITextView *) tView {
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        [tView scrollRangeToVisible:[tView selectedRange]];
    }
}

Я нашел хакерский, но более эффективный способ решения проблемы:

- (void)textViewDidChangeSelection:(UITextView *)textView
{
    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        if ([textView.text characterAtIndex:textView.text.length-1] != ' ') {
            textView.text = [textView.text stringByAppendingString:@" "];
        }

        NSRange range0 = textView.selectedRange;
        NSRange range = range0;
        if (range0.location == textView.text.length) {
            range = NSMakeRange(range0.location - 1, range0.length);
        } else if (range0.length > 0 &&
                   range0.location + range0.length == textView.text.length) {
            range = NSMakeRange(range0.location, range0.length - 1);
        }
        if (!NSEqualRanges(range, range0)) {
            textView.selectedRange = range;
        }
    }
}

По сути, я уверен, что в текстовом поле всегда есть пробел. Затем, если пользователь пытается изменить выбор таким образом, чтобы пространство было раскрыто, измените выбор. Всегда оставляя пробел перед курсором, поле прокручивается, как и должно быть.

Наконец, если вам нужно, удалите завершающий пробел при копировании текста в модель (не показано).

Другие вопросы по тегам