Как переместить предложение исправления UITextView выше текста

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

Проблема состоит в том, что в моем UITextView предложения исправления открываются ниже текста, заставляя их быть частично затененными клавиатурой.

В приложении SMS предложения открываются выше текста. Размещение, кажется, не свойство UITextView или UITextInputTraits.

Какая-либо идея, как копировать это поведение? Спасибо!

10
задан DougW 29 December 2009 в 22:10
поделиться

4 ответа

Проблема в том, что клавиатура реализована как отдельное UIWindow, а не как вид внутри основного UIWindow, поэтому раскладка с ней сложна. Вот несколько указателей в правильном направлении:

  • Просмотрите свойство приложения -windows, чтобы найти частное UITextEffectsWindow окно и разобраться в его рамке. Это клавиатура
  • -охота через подпросмотр TextView, чтобы найти закрытый вид -окон UIAutocorrectInlinePrompt. Это автокорректный пузырь.
  • Переместите этот вложенный вид в отдельный вид обертки (добавленный в TextView), а затем переместите этот вид обертки так, чтобы он находился над вышеупомянутым окном клавиатуры.

Вы заметите два упоминания о "личном" выше. Это несет в себе все соответствующие предостережения. Понятия не имею, почему Apple допускает сохранение проблемы, когда даже их приложениям приходится работать с ней.

8
ответ дан 4 December 2019 в 01:01
поделиться

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

http://www.iphonedevsdk.com/forum/iphone-sdk-development/12641-uitextview-scroll-while-editing.html

Вот копия кода с этой страницы на случай, если оригинальная ссылка сломана:

// the amount of vertical shift upwards keep the Notes text view visible as the keyboard appears
#define kOFFSET_FOR_KEYBOARD                    140.0

// the duration of the animation for the view shift
#define kVerticalOffsetAnimationDuration        0.50

- (IBAction)textFieldDoneEditing:(id)sender
{
    [sender resignFirstResponder];
}

- (IBAction)backgroundClick:(id)sender
{
    [latitudeField resignFirstResponder];
    [longitudeField resignFirstResponder];
    [notesField resignFirstResponder];

    if (viewShifted)
    {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:kVerticalOffsetAnimationDuration];

        CGRect rect = self.view.frame;
        rect.origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
        self.view.frame = rect;

        [UIView commitAnimations];

        viewShifted = FALSE;
    }       
}

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    if (!viewShifted) {     // don't shift if it's already shifted

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:kVerticalOffsetAnimationDuration];

        CGRect rect = self.view.frame;      
        rect.origin.y -= kOFFSET_FOR_KEYBOARD;
        rect.size.height += kOFFSET_FOR_KEYBOARD;
        self.view.frame = rect;

        [UIView commitAnimations];

        viewShifted = TRUE;
    }
    return YES;
}
-2
ответ дан 4 December 2019 в 01:01
поделиться

Если в нижней части вашего UITextView очищается клавиатура, вы должны иметь возможность просто изменить размер UITextView, чтобы он был достаточно высоким для просмотра исправлений. Сами исправления не отображаются за пределами рамки UITextView.

Если вы хотите сымитировать то, что вы получаете в SMS-приложении (исправления выше), вам, вероятно, придется свернуть свое собственное.

.
0
ответ дан 4 December 2019 в 01:01
поделиться

Выполняя поиск UIAutocorrectInlinePrompt в переопределенном или измененном layoutSubViews, можно изменить макет исправления, чтобы он отображался выше. Вы можете сделать это, не вызывая каких-либо частных API-интерфейсов, ища подвиды определенных классов, расположенные так, как вы от них ожидаете. В этом примере выясняется, какое представление является каким, проверяется, что исправление еще не находится над текстом, и перемещается исправление выше, и рисуется в окне так, чтобы оно не было ограничено самим UITextView. Очевидно, что если Apple изменит базовую реализацию, это не приведет к исправлению. Добавьте это к своей переопределенной или измененной реализации layoutSubViews.

- (void) moveSpellingCorrection {
 for (UIView *view in self.subviews)
 {
  if ([[[view class] description] isEqualToString:@"UIAutocorrectInlinePrompt"])
  {
   UIView *correctionShadowView = nil; // [view correctionShadowView];

   for (UIView *subview in view.subviews)
   {
    if ([[[subview class] description] isEqualToString:@"UIAutocorrectShadowView"])
    {
     correctionShadowView = subview;
     break;
    }
   }

   if (correctionShadowView)
   {
    UIView *typedTextView = nil; //[view typedTextView];
    UIView *correctionView = nil; //[view correctionView];

    for (UIView *subview in view.subviews)
    {
     if ([[[subview class] description] isEqualToString:@"UIAutocorrectTextView"])
     {
      if (CGRectContainsRect(correctionShadowView.frame,subview.frame))
      {
       correctionView = subview;
      }
      else
      { 
       typedTextView = subview;
      }
     }

    }
    if (correctionView && typedTextView)
    {

     CGRect textRect = [typedTextView frame];
     CGRect correctionRect = [correctionView frame];
     if (textRect.origin.y < correctionRect.origin.y)
     {
      CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0,-50.0);
      [correctionView setTransform: moveUp];
      [correctionShadowView setTransform: moveUp];

      CGRect windowPos = [self convertRect: view.frame toView: nil ];
      [view removeFromSuperview];
      [self.window addSubview: view];
      view.frame = windowPos;
     }

    }
   }

  }

 }
}
3
ответ дан 4 December 2019 в 01:01
поделиться