如何才能让UITextView只在文本满时滚动

时间:2012-07-04 17:15:57

标签: iphone objective-c ios xcode textview

我有这个UITextView效果很好,但是我无法让UITextView内的文字在UITextView的大小接近完全后才开始滚动,UITextView是4行高,但是当我到达第2行时,第1行被推高,我不希望视图开始滚动直到我到达5行。 scrollingEnabled = NO使其完全不滚动,因此无效。

UITextView *barf_ = [[UITextView alloc] initWithFrame:CGRectMake(20.0, 310.0, 155, 50)];

barf_.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);

//[barf_ scrollRangeToVisible:NSMakeRange([barf_.text length], 0)];

barf_.layer.cornerRadius = 3.0f;

barf_.layer.borderWidth = 0.5f;

barf_.font = [UIFont fontWithName:@"Helvetica" size:13];

4 个答案:

答案 0 :(得分:2)

加载UITextView时,将scrollEnabled设置为NO。然后将文本视图的委托设置为self或其他一些对象并实现UITextViewDelegate方法

- (void)textViewDidChange:(UITextView *)textView

只要用户对视图内的文本进行更改,就会调用此方法。在此方法中,您需要确定文本的大小以及文本是否超出文本视图的范围。如果是这样,您启用滚动。使用此方法:

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode

这是NSString上的UIKit类别方法。它返回一个CGSize,它将告诉你调用它的任何文本字符串的高度。在你的情况下,它会像

CGSize textSize = [textView.text sizeWithFont:textView.font
                            constrainedToSize:CGSizeMake(textView.frame.size.width, MAXFLOAT)
                                lineBreakMode:UILineBreakModeWordWrap];
if (textSize.height > textView.frame.size.height) {
    textView.scrollEnabled = YES;
} else {
    textView.scrollEnabled = NO;
}

答案 1 :(得分:2)

我找到答案,正如其他有类似问题的人提到的那样,使用一个小的textView,它会自动在底部添加32个填充。

一个简单的解决方法是在YourTextView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);方法中添加shouldChangeTextInRange,这解决了我的问题!

答案 2 :(得分:2)

设置contentInset可能有助于文本在UITextView内更准确地显示。但是,它不会帮助解决UITextView已启用滚动的问题,尽管没有更多文本可供查看。

同样,sizeWithFont等方法也有局限性。正如Mike Weller的优秀博客系列iOS Development: You're Doing It Wrong中所解释的那样,NSString并不是一个很好的对象,可以询问UIView应该有多大。许多UIView子类(例如UILabelUIButton等等都有插图和其他注意事项,在调整大小时必须考虑这些因素。 UITextLabel也不例外。

迈克韦勒关于这个主题的特别条目是:

You're Doing It Wrong #2: Sizing labels with -[NSString sizeWithFont:...]

iOS 7承诺在UITextView中使用textContainerInset等属性进行更复杂的文本处理。但是在此期间该怎么办?

嗯,首先我们知道UITextViewUIScrollView的子类。因此,如果contentSize大于视图的bounds属性,则滚动视图将滚动,以便我们可以看到更多内容的黄金法则。

contentSize再次检出bounds因为我们知道UIScrollView已经在根据文字计算是否应该滚动,而且&# 39;给我们错误的答案。

这是任意调整值拯救的地方!对我来说,这个值是17.f。对你而言 - 取决于你的字体 - 它可能不同。然后我们控制并决定是否应该允许滚动视图滚动:

static const CGFloat kArbritaryHeight = 17.f;
CGFloat adjustedContentHeight = myTextView.contentSize.height - kArbritaryHeight;
CGFloat boundsHeight = CGRectGetHeight(myTextView.bounds);
BOOL tooMuchContent = adjustedContentHeight > boundsHeight;

if (tooMuchContent)
{
    myTextView.scrollEnabled = YES;
}
else
{
    myTextView.scrollEnabled = NO;
}

答案 3 :(得分:0)

您可以使用sizeWithFont:constrainedToSize:lineBreakMode:方法检查字符串是否实际渲染大于文本视图,并查看是否需要启用滚动。但是,无论何时设置了滚动视图中的文本,您都必须调用它。

例如:

CGSize barfStringSize = [barfString sizeWithFont:[barf_ font] 
                               constrainedToSize:CGSizeMake(barf_.bounds.size.width, MAXFLOAT) 
                                   lineBreakMode:UILineBreakModeWordWrap]
[barf_ setScrollEnabled:barfStringSize.height > barf_.bounds.size.height]