iMessage 扩展:子视图控制器中的 UITextView,滚动行为有多个问题

iMessage Extension: UITextView in Child View Controller, scrolling behaviour has multiple issues

我在 iMessage 扩展中有一个非常基本的视图控制器。 (当然是扩展视图)。我知道您不能在精简视图中使用键盘输入...

UITextView 被限制在其上方和下方的元素中。它有一个设定的高度和宽度。约束都井井有条,没有被打破。

界面生成器中文本视图的所有选项都保留为默认值。

UITextView 出现以下问题:

  1. 当我开始编辑时,光标几乎看不见。 (在场地的底部,垂直切断的一半)。

  2. 键入第一个字母会将光标置于文本视图的垂直中心。

  3. 换行,然后输入一个字符,光标再次向下。

  4. 然后在此之后键入后续字符将使光标再次回到垂直中心。并且每隔一个字符再次将整个文本视图滚动到底部。所以每次击键都会出现这种奇怪的上下弹跳行为。

  5. 当我滚动时,右侧的滚动条视觉提示没有反映文本视图的正确高度。 (滚动条只下降到文本视图高度的一半。)

我希望 UITextView 默认像这样工作:

  1. 激活和编辑时,光标应移至文本视图的顶部。

  2. 在换行后键入键时,文本视图不应跳转。

  3. 垂直滚动条指示器应显示文本字段的整个范围,而不是一半。

因此,显然文本视图中的内部滚动视图在确定事物的大小方面存在问题。

有谁知道,如果这是 iMessage 特有的问题,或者是否有人在 iMessage 之外也遇到过这个问题,以及如何解决?

我的IB约束(倒数第二个视图是文本视图):

问题视频演示: https://youtu.be/1bkvHnkXLWM

更新:我正在使用子视图控制器将我的视图控制器嵌入到根控制器中。我尝试了一个空白的 Hello World 应用程序,默认情况下 UITextView 正常工作。因此,这个问题与我嵌入子视图控制器的方式有关。

这是我用来嵌入我的子视图控制器的代码:

- (void)showViewController:(UIViewController*)vcToShow isPop:(BOOL)isPop
{
    NSLog(@"Presenting Controller: %@", vcToShow);
    [self.activeVC willMoveToParentViewController:nil];
    [self addChildViewController:vcToShow];

    vcToShow.view.translatesAutoresizingMaskIntoConstraints = NO;
    vcToShow.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.rootView addControls:@[vcToShow.view]
    align:VerticalAlignStretchToFullHeight];

    UIViewController* currentVC = self.activeVC;
    self.activeVC = vcToShow;
    vcToShow.view.alpha = 0.0f;

    [self transitionFromViewController:currentVC
        toViewController:vcToShow
        duration:0.3
        options:UIViewAnimationOptionTransitionNone
        animations:^{

            vcToShow.view.alpha = 1.0f;
        }
        completion:^(BOOL finished) {
            [currentVC removeFromParentViewController];
            [vcToShow didMoveToParentViewController:self];
            [self updateScreenState];

            if (isPop) {
                [self removeReferenceToController:currentVC];
            }
        }];
}

我有办法。

我没有使用 Interface Builder 来放置我的 UITextView,而是使用我自己的编程约束生成方法来创建和放置 UITextView,仅在 ViewDidAppear 之后。

我怀疑在界面生成器呈现子视图 VC 时,它没有填充 UITextView 的内部滚动视图所需的所有内容。因此,滚动视图使用错误的维度值进行了初始化,因此会在任何与滚动相关的内容上出现故障。在以编程方式(在 Child VC 中)完成 viewDidAppear 中的所有操作后,文本视图现在可以正确滚动,并且光标始终位于开头,按预期工作。

更新码:

  1. 将 UITextView 完全从界面生成器中移除。

  2. 以编程方式添加(从 viewDidAppear 调用):

    self.textView = [[UITextView alloc] init];
    self.textView.translatesAutoresizingMaskIntoConstraints = NO;
    
    CGFloat topPadding = self.instructionLabel.frame.origin.y + self.instructionLabel.frame.size.height + TEXT_VIEW_TOP_PADDING;
    
    // This custom method generates Visual Constraint format for me
    // so i don't have to write manual individual constraint syntax. 
    [self.rootView addControls:@[self.textView]
        align:VerticalAlignTop
        withHeight:TEXT_VIEW_HEIGHT
        verticalPadding: 0
        horizontalPadding: 20
        topPadding: topPadding];