30

我有一个UITextView包含在一个UITableViewCell. 最初显示视图时布局是正确的,但是一旦我单击UITextView它,它就会自动向上滚动一点,并且第一行的上半部分字符变得不可见。

此图像是UITextView不活动的:
UITextView 不活动 http://gerodt.homeip.net/uitextview-notactive.png

而这个是当我点击UITextView使其处于活动状态时:
UITextView active http://gerodt.homeip.net/uitextview-active.png

我根本没有 UITextView 向上滚动,它应该简单地保持固定。我怎样才能做到这一点?我已经在 中尝试了几种设置Interface Builder,但到目前为止还没有运气。

任何建议表示赞赏。

下吕

4

6 回答 6

61

UITextView 是 UIScrollView 的子类,所以它有一个可配置的 contentInset 属性。不幸的是,如果您尝试更改 UITextView 实例上的 contentInset,底部边缘插图总是会重置为 32。我之前遇到过短 UITextView 帧并发现这是一个问题。我怀疑这是导致您的问题的原因,但是您应该在调试器中检查 textview 的 contentInset 以确定。

解决方法/解决方案很简单:继承 UITextView 并覆盖 contentInset 方法,以便它始终返回 UIEdgeInsetZero。试试这个:

//
// BCTextView
//
// UITextView seems to automatically be resetting the contentInset
// bottom margin to 32.0f, causing strange scroll behavior in our small
// textView.  Maybe there is a setting for this, but it seems like odd behavior.
// override contentInset to always be zero.
//
@interface BCZeroEdgeTextView : UITextView
@end

@implementation BCZeroEdgeTextView

- (UIEdgeInsets) contentInset { return UIEdgeInsetsZero; }

@end 
于 2009-12-08T02:22:10.927 回答
16

这就是根据 Apple 工程师的意图 UITextView 的行为方式,并且 UITextView 适用于高度至少为几行的文本。对此没有解决方法,请改用 UITextField 或将 UITextView 增加到至少 3 行的高度。

于 2009-07-24T18:45:18.543 回答
6

你也可以这样做:

textView.contentInset=UIEdgeInsetsZero;

在您的委托文件中。

于 2011-09-05T00:56:08.893 回答
2

UITextView是 的子类UIScrollView,因此答案涉及contentOffset属性,即正在更改的内容,而不是插入或内容大小。如果视图首次出现时滚动位置正确,则可以存储内容偏移量以供以后调用。

YourViewController.h 被剪断

@interface YourViewController : UIViewController <UITextViewDelegate, UIScrollViewDelegate>

@property(nonatomic, weak) IBOutlet UITextView *textView;

@end

YourViewController.m 片段

@implementation YourViewController {
@private
    BOOL _freezeScrolling;
    CGFloat _lastContentOffsetY;
}

// UITextViewDelegate
- (void)textViewDidBeginEditing:(UITextView *)textView {
    // tell the view to hold the scrolling
    _freezeScrolling = YES;
    _lastContentOffsetY = self.textView.contentOffset.y;
}

// UITextViewDelegate
- (void)textViewDidEndEditing:(UITextView *)textView {
    _freezeScrolling = NO;
}

// UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (_freezeScrolling) {
        // prevent the scroll view from actually scrolling when we don't want it to
        [self repositionScrollView:scrollView newOffset:CGPointMake(scrollView.contentOffset.x, _lastContentOffsetY)];
    }
}

// UIScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // scroll prevention should only be a given scroll event and turned back off afterward
    _freezeScrolling = NO;
}

// UIScrollViewDelegate
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    // when the layout is redrawn, scrolling animates. this ensures that we are freeing the view to scroll
    _freezeScrolling = NO;
}

/**
 This method allows for changing of the content offset for a UIScrollView without triggering the scrollViewDidScroll: delegate method.
 */
- (void)repositionScrollView:(UIScrollView *)scrollView newOffset:(CGPoint)offset {
    CGRect scrollBounds = scrollView.bounds;
    scrollBounds.origin = offset;
    scrollView.bounds = scrollBounds;
}

在上面的代码示例中还需要注意的是最后一种方法。调用任何类型的setContentOffset:实际上都会触发滚动,从而导致调用scrollViewDidScroll:. 所以调用setContentOffset:会导致无限循环。设置滚动边界是解决此问题的方法。

简而言之,UITextView当我们检测到用户选择了要编辑的文本时,我们告诉视图控制器阻止滚动。我们还存储当前内容偏移量(因为我们知道该位置是我们想要的)。如果UITextView尝试滚动,那么我们将内容偏移保持在适当的位置,直到滚动停止(这会触发scrollViewDidEndDecelerating:scrollViewDidEndScrollingAnimation:)。当用户完成编辑时,我们也会解冻滚动。

请记住,这是一个基本示例,因此您需要根据您想要的确切行为调整代码。

于 2015-06-23T22:12:07.347 回答
1

我遇到了与不需要的UITextView滚动类似的问题。我终于设法通过在我的末尾重置 contentSize 来解决它keyboardDidShow:

- (void)keyboardDidShow:(NSNotification *)notification {
  textView.contentSize = CGSizeZero;
}

您还需要注册键盘通知,如下所示:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];

在我的情况下,我不想要任何滚动,因为我正在将框架重置为 textView 的高度(contentSizetextViewDidChangea 中增长 textview UIScrollView)。

于 2011-08-26T13:38:20.460 回答
0

尝试在 textview 上放置 Redraw 而不是 Scale to Fill。您可能仍然需要捕获委托并保持内容偏移,但它至少应该防止跳转到点 (0,0)。还必须关闭 Autoresizes 子视图。每次我也跳到 textview 的顶部,这解决了这个问题。

在此处输入图像描述

于 2014-05-13T02:55:42.340 回答