【问题标题】:iOS7 UITextView contentsize.height alternativeiOS7 UITextView contentsize.height 替代
【发布时间】:2013-10-02 10:49:57
【问题描述】:

我正在将其中一个应用程序从 iOS 6.1 移植到 iOS 7。我使用的布局是 UITextView 具有固定宽度,但它的高度取决于其内容大小。对于 iOS 6.1,检查 contentsize.height 并将其设置为 textview 的框架高度就足够了,但它在 iOS 7 上不起作用。

然后我怎样才能创建一个具有固定宽度但动态高度基于它显示的文本的UITextView

注意:我是通过代码创建这些视图,而不是使用 Interface Builder。

【问题讨论】:

    标签: ios uitextview ios7


    【解决方案1】:

    使用以下代码,您可以根据固定宽度更改 UITextView 的高度(它适用于 iOS 7 和以前的版本):

    - (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;
    }
    

    使用此函数,您将获取一个 NSAttributedString 和一个固定宽度来返回所需的高度。

    如果你想从你的特定字体的文本中计算框架,需要使用下面的代码:

    - (CGSize)text:(NSString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
    {
        if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
        {
            CGRect frame = [text boundingRectWithSize:size
                                              options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                           attributes:@{NSFontAttributeName:font}
                                              context:nil];
            return frame.size;
        }
        else
        {
            return [text sizeWithFont:font constrainedToSize:size];
        }
    }
    

    您可以将 SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO 添加到项目中的 prefix.pch 文件中:

    #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
    

    您也可以将之前的测试SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)替换为:

    if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])‌
    

    【讨论】:

    • 我只能在 24 小时后给你。耐心点,这是你的:)
    • 也许您应该链接到您从中获取的答案? stackoverflow.com/questions/18368567/…
    • @Jordan Montel,对于另一个问题,如果我有固定的宽度和高度,我怎样才能找到分配字符串的最佳字体大小?我在 iOS7 上也有类似的问题(在 iOS6 上,我可以做到)
    • @Jacky:反复试验;将大小增加或减少 1,直到其计算的高度太大。或者使其大小为 1000 并自动调整大小以适应。
    • 这个答案已经不正确了。尝试在此类文本字段中输入大量文本。突然尺寸不对?至少NSStringDrawingUsesFontLeading 是额外的
    【解决方案2】:

    这适用于 iOS6 和 7:

    CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)];
        self.myTextView.height = textViewSize.height;
    

    【讨论】:

    • 嗨,是的,这对我来说很重要……我使用的是“txtviewHeight.frame.size.height”而不是“txtviewHeight.contentSize.height”
    • 为什么我在“UITextView”类型的对象上找不到属性高度?
    • @Hexark textView.bounds.size.height
    【解决方案3】:

    在 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;
    

    【讨论】:

    • 您的回答不符合问题,但符合我的问题。所以我投票赞成:)
    • 这不会为我修复内容大小。滚动已禁用。
    • 这段代码解决了我的问题,但是你的评论中产生的方法是什么意思?
    【解决方案4】:

    使用这个小功能

    -(CGSize) getContentSize:(UITextView*) myTextView{
        return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)];
    }
    

    【讨论】:

    • 适用于我的 iOS6 和 iOS7。谢谢!
    【解决方案5】:

    我的最终解决方案基于 HotJard,但包括文本容器的顶部和底部插入,而不是使用 2*fabs(textView.contentInset.top):

    - (CGFloat)textViewHeight:(UITextView *)textView
    {
        return ceilf([textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height +
                     textView.textContainerInset.top +
                     textView.textContainerInset.bottom);
    }
    

    【讨论】:

      【解决方案6】:

      有更简单的解决方案,使用这种方法:

      +(void)adjustTextViewHeightToContent:(UITextView *)textView;
      {
          if([[UIDevice currentDevice].systemVersion floatValue] >= 7.0f){
              textView.height = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height+2*fabs(textView.contentInset.top);
          }else{
              textView.height = textView.contentSize.height;
          }
      }
      

      UPD:仅用于显示文本(isEditable = NO)

      【讨论】:

      • 您的解决方案似乎不起作用。当 textview 转到第二行时usedRectForTextContainer 方法返回相同的高度。
      • 哦,可能吧,我只是用来显示文字
      【解决方案7】:
         _textView.textContainerInset = UIEdgeInsetsZero;
         _textView.textContainer.lineFragmentPadding = 0;
      

      别忘了 lineFragmentPadding

      【讨论】:

        【解决方案8】:

        简单的解决方案 - textView.isScrollEnabled = false 在另一个滚动视图或带有 UITableViewAutomaticDimension 的 tableView 单元格中完美运行

        【讨论】:

          【解决方案9】:

          @Ana 的,@Blake Hamilton 在 swift 中的解决方案。

          var contentHeight: CGFloat = textView.sizeThatFits(textView.frame.size).height
          

          对我来说好处是,当 isScrollEnable 设置为 false 时,这也会返回正确的 contentSize。设置为 false 返回文本视图的框架大小而不是内容大小。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-05
            • 2014-04-19
            • 1970-01-01
            • 2015-10-18
            • 1970-01-01
            • 2016-02-07
            相关资源
            最近更新 更多