【问题标题】:UITextView content size different in iOS7iOS7中的UITextView内容大小不同
【发布时间】:2013-10-03 12:39:10
【问题描述】:

我正在使用UITextView,可以通过点击“更多”按钮进行扩展。问题如下:

在 iOS6 上我使用这个,

self.DescriptionTextView.text =  @"loong string";

if(self.DescriptionTextView.contentSize.height>self.DescriptionTextView.frame.size.height) { 
    //set up the more button
}

问题在于,在 iOS7 上,contentSize.height 返回的值与它在 iOS6 上返回的值不同(远小于)。 为什么是这样?如何解决?

【问题讨论】:

    标签: ios objective-c cocoa-touch ios7 uitextview


    【解决方案1】:

    内容大小属性不再像在 iOS 6 上那样工作。使用其他人建议的 sizeToFit 可能会或可能不会工作,具体取决于多种因素。

    它对我不起作用,所以我改用它:

    - (CGFloat)measureHeightOfUITextView:(UITextView *)textView
    {
        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
        {
            // This is the code for iOS 7. contentSize no longer returns the correct value, so
            // we have to calculate it.
            //
            // This is partly borrowed from HPGrowingTextView, but I've replaced the
            // magic fudge factors with the calculated values (having worked out where
            // they came from)
    
            CGRect frame = textView.bounds;
    
            // Take account of the padding added around the text.
    
            UIEdgeInsets textContainerInsets = textView.textContainerInset;
            UIEdgeInsets contentInsets = textView.contentInset;
    
            CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right;
            CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom;
    
            frame.size.width -= leftRightPadding;
            frame.size.height -= topBottomPadding;
    
            NSString *textToMeasure = textView.text;
            if ([textToMeasure hasSuffix:@"\n"])
            {
                textToMeasure = [NSString stringWithFormat:@"%@-", textView.text];
            }
    
            // NSString class method: boundingRectWithSize:options:attributes:context is
            // available only on ios7.0 sdk.
    
            NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
            [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
    
            NSDictionary *attributes = @{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle };
    
            CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)
                                                      options:NSStringDrawingUsesLineFragmentOrigin
                                                   attributes:attributes
                                                      context:nil];
    
            CGFloat measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding);
            return measuredHeight;
        }
        else
        {
            return textView.contentSize.height;
        }
    }
    

    【讨论】:

    • 谢谢,这看起来不错。你能帮忙解决另一个类似的问题吗? stackoverflow.com/questions/19029018/…
    • 下一个iOS版本检查很容易使用:if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
    • 迄今为止我见过的最好的解决方法是处理 iOS 7 引起的 contentSize.height 问题。我只想提一提的是,最好检查系统版本,以防 snapshotViewAfterScreenUpdates 发生变化。
    • 我已经更新了代码以检查 iOS 7 与系统版本。
    • 好的,这是我想要的:在 iOS 7.1 中已修复(好消息!)。对于 iOS 7.0.x,按此处所述计算 contentSize(或对于像这样的非属性字符串:CGFloat textViewheight = [self.textView sizeThatFits:CGSizeMake(self.textView.frame.size.width, FLT_MAX)].height; 然后将 textview 的高度约束的常量设置为该高度。(您很可能不应该在自动布局场景中与框架鬼混)
    【解决方案2】:

    试试下面链接的答案,layoutIfNeeded应该在contentSize之前调用。

    iOS7 UITextView contentsize.height alternative

    答案:

    在 iOS7 中,UITextView 使用 NSLayoutManager 来布局文本:

    // If YES, then the layout manager may perform glyph generation and layout for a given portion of the text, without having glyphs or layout for preceding portions.  The default is NO.  Turning this setting on will significantly alter which portions of the text will have glyph generation or layout performed when a given generation-causing method is invoked.  It also gives significant performance benefits, especially for large documents.
    @property(NS_NONATOMIC_IOSONLY) BOOL allowsNonContiguousLayout;
    

    禁用allowsNonContiguousLayout 以修复contentSize

    textView.layoutManager.allowsNonContiguousLayout = NO;
    

    【讨论】:

    • 根据文档,allowsNonContiguousLayout 默认设置为 false。是否存在设置为 true 需要手动重置的情况?
    • @Lope 我认为默认情况下您自己制作的布局管理器可能是错误的,但对于 textview 制作的布局管理器默认情况下它是正确的。将其设置回 false 解决了我的布局问题。谢谢,@nova!
    【解决方案3】:

    这个link 似乎有答案。

    您必须先使用sizeToFit,然后才能使用contentSize

    【讨论】:

    • 链接说 sizeToFit 曾经在 iOS 6 中工作,但现在在 iOS 7 中还有一些额外的解决方法。
    【解决方案4】:

    试试下面的代码,iOS6和7都可以,请试试看。

    CGSize myTextViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)];
    self.myTextView.height = myTextViewSize.height;
    NSLog(@"%f", self.myTextView.height);
    

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 1970-01-01
      • 2014-01-18
      • 2013-10-24
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      相关资源
      最近更新 更多