高度达到8192.0后,UITextView文本变为不可见

时间:2014-05-10 14:52:12

标签: ios uiscrollview uitextview

我在UITextView中嵌入了不可滚动的UIScrollView,并动态地向UITextView添加了文字。 UIScrollView根据TextView的框架相应地调整它的contentSize。但是,一旦UITextView超过8192的高度,文本将变为不可见(但仍然存在,因为您可以使用放大镜突出显示文本,甚至可以通过放大镜查看部分文本)。

  CGRect textviewFrame = self.TextView.frame;
  textviewFrame.size.height = [self textViewHeightForAttributedText:self.TextView.attributedText andWidth:320.0];
  self.TextView.frame = textviewFrame;
  self.ScrollView.contentSize = self.TextView.frame.size;

帮助函数相应地调整UITextView的大小:

- (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width
{
  UITextView *textView = [[UITextView alloc] init];
  [textView setAttributedText:text];
  CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)];
  return size.height;
}

没有意识到这是与未解决here相同的问题,直到我通过强制将最大大小强制为8193并且问题发生(而最大大小为8192仍然显示文本)来明确测试它正确)。有人在遇到这个问题并且知道一个解决方法吗?感谢

4 个答案:

答案 0 :(得分:5)

我最近遇到了这个问题并且已经找到了解决它的有效方法。虽然它似乎是一个iOS错误恕我直言,它真的不是...... CALayer尺寸有实际限制,加上绘制8K高文本需要很长时间。更好的做法就像苹果所期望的那样,只渲染一些可见的文本......这就是为什么UITextView毕竟扩展了UIScrollView的原因。

问题是UITextView与其他UI的集成并不容易。在我的情况下,我正在开发一个新闻应用程序,其中使用单个UITextView来呈现文章,以及它上面和下面的一些单独的UI(标题和按钮等),所有这些都托管在一个可滚动的容器中。 / p>

我发现的解决方案是将UITextView拆分为两个视图......一个专用的UITextView容器,其框架是全文大小(即UITextView的contentSize大小相同),这是您的UITextView的超级视图。您的子UITextView框架应设置为外部可滚动容器的边界。

然后你要做的就是使用键值观察来监视外部可滚动容器视图的contentOffset属性(在我的例子中,这是一个UICollectionView)。当其contentOffset更改时,您更新(1)UITextView的contentOffset,以及(2)UITextView图层的transform属性。通过更新该转换属性,UITextView被修复以填充其超级视图的当前可见部分。但是因为你也在更新UITextView的contentOffset,这个技巧对于用户来说是完全不可见的......它的外观和行为就好像UITextView非常大。

答案 1 :(得分:1)

这是一个功能齐全的解决方案,适合任何喜欢它的人!

**假设您的内容大小不会超过两个文字视图的限制**

此解决方案的工作原理是在视图中添加两个UITextView,并在它们之间拆分文本。它看起来很复杂,但实际上非常简单!我刚刚写了一篇非常冗长的描述:)

第1步 - 在视图中添加两个UITextView:

我在故事板中添加了我的。放置它们使一个直接位于另一个之上,它们之间没有空隙。不要担心设置高度(我们稍后会设置)。

在视图上设置约束,使它们从顶部和底部彼此连接,并从所有其他边绑定容器的周围边缘,包括所需的填充。 将第一个文本视图从顶部,左侧和右侧绑定到容器,并从底部绑定到第二个文本视图。将第二个文本视图从底部,左侧和右侧绑定到容器,并从顶部绑定到第一个文本视图。这将确保在设置内容时它们适当地伸展。

不要对视图的高度设置任何约束,或者如果必须(为了避免来自约束检查器的警告),请将其中一个视图的高度设置为>= 20,或者某些类似的小视图号。

禁用文本视图的滚动,弹跳和滚动指示器。此解决方案依赖于视图是固定的,不可滚动的高度,因此如果您希望滚动内容,则应使用UIScrollView或UITableViewCell作为容器。

在视图控制器文件中为您的两个新文本视图创建插座,并为其命名为textView1textView2

第2步 - 将textContainerInsets设置为零:

使用用户定义的运行时属性将两个文本视图上的textContainerInset属性设置为零:

或代码:

self.textView1.textContainerInset = UIEdgeInsetsZero;
self.textView2.textContainerInset = UIEdgeInsetsZero;

这将确保在设置内容时两个视图之间不显示可见空间,并且不应影响视图周围的其他间距。

第3步 - 拆分内容,设置内容并更新视图高度:

只需将以下代码复制到视图控制器文件(viewDidLoad)中,然后将contentString变量设置为您的内容。

/* Content is split across two UITextViews to avoid max drawing height */

NSString *contentString = @"Some very long piece of text...";

// Set text
NSArray *components = [contentString componentsSeparatedByString:@"\n"];
NSInteger halfLength = [components count] / 2;
NSArray *firstHalf = [components subarrayWithRange:NSMakeRange(0, halfLength)];
NSArray *secondHalf = [components subarrayWithRange:NSMakeRange(halfLength, [components count] - halfLength)];
NSString *contentString1 = [firstHalf componentsJoinedByString:@"\n"];
NSString *contentString2 = [secondHalf componentsJoinedByString:@"\n"];
self.textView1.text = contentString1;
self.textView2.text = contentString2;

// Set text view heights
CGFloat fixedWidth1 = self.textView1.frame.size.width;
CGFloat fixedWidth2 = self.textView2.frame.size.width;
CGSize newSize1 = [self.textView1 sizeThatFits:CGSizeMake(fixedWidth1, CGFLOAT_MAX)];
CGSize newSize2 = [self.textView2 sizeThatFits:CGSizeMake(fixedWidth2, CGFLOAT_MAX)];
CGRect newFrame1 = self.textView1.frame;
CGRect newFrame2 = self.textView2.frame;
newFrame1.size = CGSizeMake(fmaxf(newSize1.width, fixedWidth1), MIN(newSize1.height, 8192));
newFrame2.size = CGSizeMake(fmaxf(newSize2.width, fixedWidth2), MIN(newSize2.height, 8192));
self.textView1.frame = newFrame1;
self.textView2.frame = newFrame2;

此代码大致在中间拆分contentString,寻找最近的换行符。如果您想将内容拆分为其他字符,只需将上面\n的所有匹配项更改为您要拆分的内容。

第4步 - 设置容器视图高度:

将容器视图(scrollView,tableViewCell,等等)设置为两个文本视图的高度,以及您在其上方和下方设置的任何其他空间。

CGRect viewFrame = self.myView.frame;
viewFrame.size.height = MIN(self.textView1.frame.size.height, 8192) + MIN(self.textView2.frame.size.height, 8192) + kTextViewContainerPadding;
[self.myView setFrame:viewFrame];

(在我的代码中,kTextViewContainerPadding是一个宏,我将其设置为我的两个文本视图上方和下方的空间之和,在它们的容器中)。

就是这样!祝你好运。

答案 2 :(得分:0)

尝试为scrollView启用滚动。 保持textView的高度>内容的高度,以便实际上不会滚动,但是scrollEnabled应该为= YES

它为我解决了问题。

答案 3 :(得分:-5)

您好我觉得回答不迟。我遇到了和你一样的问题。这是我的解决方案:

textView.scrollEnabled = YES;    
contentTextView.attributedText = finalAttrString;
// contentTextView.text = [attrString string];
contentTextView.font = kFont(contentTextFS + [valueOfStepper intValue]);

[contentTextView sizeToFit];
contentTextView.height += 1;//This is the key code
//contentTextView.height = 8192.0f

我解决了这个问题,我可以在iOS 8上更改大小dynamic.Successfull