iOS 7中,在编辑UITextView时,光标位置不正确。为什么?

23

为什么会发生这种事情

上面的黄色框是一个可编辑的UITextView,目前正在进行编辑(是第一响应者)。但你可能看不出来,因为没有光标。但实际上有光标……它就是位于黄色textView左下角的那个小蓝点。它略低于textView的底部边界。因此,如果我继续换行或按回车键,文本将自然地向上移动。但光标从未“水平”,或在UITextView的底部边界正上方。它总是刚好从底部探出来,比边界低几个点。

为什么?这在iOS 6中不是问题。有任何方法可以解决这个问题吗?


我遇到了同样的情况,我将那个UITextView设置成可滚动的,这对我起作用了。这有点奇怪,但对我有用。 - iOS_Developer
5个回答

41

这个bug在iOS 7.0中存在,你可以通过修改textView代理方法来解决它。

尝试下面的代码

- (void)textViewDidChange:(UITextView *)textView {
    CGRect line = [textView caretRectForPosition:
        textView.selectedTextRange.start];
    CGFloat overflow = line.origin.y + line.size.height
        - ( textView.contentOffset.y + textView.bounds.size.height
        - textView.contentInset.bottom - textView.contentInset.top );
    if ( overflow > 0 ) {
    // We are at the bottom of the visible text and introduced a line feed, scroll down (iOS 7 does not do it)
    // Scroll caret to visible area
        CGPoint offset = textView.contentOffset;
        offset.y += overflow + 7; // leave 7 pixels margin
    // Cannot animate with setContentOffset:animated: or caret will not appear
        [UIView animateWithDuration:.2 animations:^{
            [textView setContentOffset:offset];
        }];
    }
}

您的问题将会得到解决。


对我来说,它运行得很好,我没有遇到你所说的问题。 - Pratik
关于这个解决方案的一个注释:我发现只有当你输入在框架底部以上时,它才有效。如果你在textView的contentOffset底部处输入(假设你已经为contentOffset的底部值分配了一个值),这并不总是有效。 - Joe
2
Pratik的答案在CGRect行处崩溃=[textView caretRectForPosition:textView.selectedTextRange.start],其中line.origin.y返回为inf。 有人有解决这个崩溃问题的方法吗? - Shilpi
1
@任何人:我们为什么需要7像素边距?这是确定的吗? - selva
2
@Shilpi 是完全正确的,这段代码在某些情况下会崩溃。我还没有进行足够的调试。直到进一步调试,将if语句设置为if (overflow > 0 && !isnan(line.origin.y) && !isinf(line.origin.y))应该足以防止文本视图的setContentOffset:内部崩溃。 - smileyborg
显示剩余4条评论

3
如果你使用导航控制器,我认为这实际上是iOS 7中引入的一个属性的结果:automaticallyAdjustsScrollViewInsets(请参见iOS 7过渡指南)。
默认情况下,此属性为YES,并会尝试通过调整导航控制器高度的滚动偏移量来优化UITextView(它本身就是一个滚动视图)。
因此,解决方案是在viewDidLoad中将此属性设置为NO(要小心不要在iOS 6上调用它,因为它仅适用于iOS 7及以上版本)。

-1
根据Todd的回答,您可以将类似以下代码放入应用程序启动完成后运行的方法中:
   [[UITextView appearance] setTintColor:[UIColor redColor]];
   [[UITextField appearance] setTintColor:[UIColor redColor]];

这将影响所有的UITextFields和UITextViews。


5
调整色彩深度跟光标位置有什么关系? - Joe
我在这里寻找解决我的光标不可见问题的方法,发现了Todd的答案解决了我的问题。我将这个答案作为对Todd答案的改进添加了进去。 - tavi

-1
- (BOOL) textView:(UITextView *)sender shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSString * newText = [sender.text stringByReplacingCharactersInRange:range withString:text];
    [self setFramesForText:newText];

    if (!IOS_VERSION_6_OR_LESS) {
        if ([text isEqualToString:@"\n"]){
            [textView setContentOffset:CGPointMake(textView.contentOffset.x, 999999999)];
        }
    }

    return YES;
}

-3

您只需要设置UITextView的tintColor即可。

将以下内容放入代码中(我将其放在了viewDidLoad中),对我来说起作用。

self.textView.tintColor = [UIColor redColor];

1
到目前为止,这是最好的解决方案。 - Unheilig
3
这会改变光标的颜色...这能解决问题吗? - Joe
5
我非常渴望与iOS 7中UITextView相关的解决方案,以至于我实际上尝试了这个方法。红色没有起作用,但橙色可以。 - bilobatum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接