草庐IT

iphone - 具有自动布局的 UIView,获取他的大小

coder 2023-07-26 原文

我有一个 UIView 女巫以编程方式填充内容。此 UIView 中的布局是使用自动布局进行的。

这个 View 需要是一个UIScrollView的 subview ,并且需要垂直滚动。

我有这样的代码:

// self.scrollview is defined in IB and it has constraints to edges (margin:0 0 0 0)

UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, MAXFLOAT)];
[contentView setTranslatesAutoresizingMaskIntoConstraints:YES];

// Then I call some my parser which add subviews to the contentView and layout them using constraints.

[self.scrollview addSubview:contentView];
[contentView setNeedsLayout];
[contentView layoutIfNeeded];

// Now, I need to know height of the contentView to be able to set contentSize to self.scrollview

//更新

好的,我有这个 UILabel,添加到 self.content,它是 UIView 创建的:[[UIView alloc] initWithFrame:CGRectMake(self.layoutMargin, self.layoutMargin, 1024 - self.layoutMargin*2, 100 )]);

这个 self.content View 对我来说只是容器,需要放在一些 UIScrollView 中。我需要 self.content 的高度来设置 UIScrollView 的 contentSize。

[self.content setTranslatesAutoresizingMaskIntoConstraints:YES];

[self.content setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.content setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];

UILabel *textlabel = [[UILabel alloc] init];
UIFont *font;


font = [UIFont fontWithName:@"InterstatePlus-Regular" size:16];

UIFont *bold;

bold = [UIFont fontWithName:@"InterstatePlus-Bold" size:16];
NSDictionary *style = @{
                        @"$default" : @{NSFontAttributeName  : font},
                        @"b"        : @{NSFontAttributeName  : bold},
                        @"em"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Italic" size:14]},
                        @"h1"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:48]},
                        @"h2"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:36]},
                        @"h3"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:32]},
                        @"h4"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:24]},
                        @"h5"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:18]},
                        @"h6"       : @{NSFontAttributeName  : [UIFont fontWithName:@"HelveticaNeue-Medium" size:16]}
                        };
[textlabel setNumberOfLines:0];



NSError *error = nil;
NSString *string = @"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing <br>Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type<br> and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
NSString *replacedString = [string stringByReplacingOccurrencesOfString:@"<br>" withString:@"\n"];
NSAttributedString *attributedString = [SLSMarkupParser attributedStringWithMarkup:replacedString style:style error:&error];
NSMutableAttributedString *mutAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString];

NSInteger strLength = [attributedString length];
NSMutableParagraphStyle *paragraphstyle = [[NSMutableParagraphStyle alloc] init];
[mutAttributedString addAttribute:NSParagraphStyleAttributeName
                            value:paragraphstyle
                            range:NSMakeRange(0, strLength)];

if (mutAttributedString) {
    textlabel.attributedText = mutAttributedString;
}


[textlabel setTranslatesAutoresizingMaskIntoConstraints:NO];

[textlabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[textlabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];


textlabel.textAlignment = NSTextAlignmentLeft;

[textlabel setTextColor:[UIColor blackColor]];

[textlabel setBackgroundColor:[UIColor clearColor]];
textlabel.lineBreakMode = NSLineBreakByWordWrapping;
[textlabel setNumberOfLines:0];
[self.content addSubview:textlabel];

[textlabel mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(self.content.mas_top).with.offset(0); 
    make.right.equalTo(self.content.mas_right).with.offset(0);
    make.height.equalTo(@1200);
    make.left.equalTo(self.content.mas_left).with.offset(0);
}];
[self.containerView addSubview:self.content];
[self.containerView setBackgroundColor:[UIColor redColor]];
[self.content setBackgroundColor:[UIColor yellowColor]];

CGSize s = [self.content systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
NSLog(@"Size: %f %f", s.width, s.height);

This is Log: Size: 17713.000000 0.000000

它看起来像:http://d.pr/i/Rxku

最佳答案

如果您使用自动布局,

sizeToFit 是错误的 API。

用于自动布局的正确 API 是 UIView systemLayoutSizeFittingSize:最有可能传递 UILayoutFittingCompressedSize。这将返回一个 CGSize,它是可以使用指定约束绑定(bind) View 的最小大小。

检查 this链接

编辑:响应已发布的附加代码...

我从未使用过 Masonry图书馆之前,但它很整洁!

UILabels 提供一个足够大的 intrinsicContentSize 来显示它们的文本。为了计算多行文本的大小,标签需要知道一个固定的尺寸,即通过 preferredMaxLayoutWidth 属性获得的所需宽度尺寸。如果您不提供 preferredMaxLayoutWidth 值(默认为 0),标签将计算固有内容大小,就好像它在布置单行文本一样。

在您的代码中,您永远不会设置标签的 preferredMaxLayoutWidth,因此依赖于标签的 intrinsicContentSize 的自动布局执行的任何布局都不会是您所期望的。

我把你的代码提炼成一个新的例子,你应该能够将它复制/粘贴到一个干净的 viewcontroller 子类中:

#import "Masonry.h"

@interface TSViewController ()
@end

@implementation TSViewController
{
    UIScrollView*   _scrollView;
    UIView*         _containerView;

    UILabel*        _titleLabel;
    UILabel*        _contentLabel;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor darkGrayColor];

    // create/configure our scrollview
    _scrollView = [UIScrollView new];
    _scrollView.translatesAutoresizingMaskIntoConstraints = NO;
    _scrollView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
    [self.view addSubview: _scrollView];

    // create/configure our container
    _containerView = [UIView new];
    _containerView.translatesAutoresizingMaskIntoConstraints = NO;
    _containerView.backgroundColor = [UIColor yellowColor];
    [_scrollView addSubview: _containerView];

    // create/configure our content - title and content labels
    _titleLabel = [UILabel new];
    _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _titleLabel.numberOfLines = 1;
    _titleLabel.font = [UIFont fontWithName: @"Courier" size: 80];
    _titleLabel.text = @"Lorem Ipsum";
    _titleLabel.backgroundColor = [UIColor lightGrayColor];
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    [_containerView addSubview: _titleLabel];

    _contentLabel = [UILabel new];
    _contentLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _contentLabel.numberOfLines = 0;
    _contentLabel.font = [UIFont fontWithName: @"Courier" size: 40];
    _contentLabel.text = self.loremIpsum;
    [_containerView addSubview: _contentLabel];

    // configure constraints for each view:

    [_scrollView mas_makeConstraints: ^(MASConstraintMaker *make) {

        // glue the scrollview to its superview with a 20 point inset:

        make.top.equalTo( self.view.mas_top ).with.offset( 20 );
        make.left.equalTo( self.view.mas_left ).with.offset( 20 );
        make.right.equalTo( self.view.mas_right ).with.offset( -20 );
        make.bottom.equalTo( self.view.mas_bottom ).with.offset( -20 );
    }];

    [_containerView mas_makeConstraints: ^(MASConstraintMaker *make) {

        // per the iOS 6.0 Release Notes, this is how to use auto-layout for a container view
        // inside a scrollview.  basically, tie the edges of the containerview to the scrollview.
        // http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/
        // see section "Here are some notes regarding Auto Layout support for UIScrollView"

        make.top.equalTo( _scrollView.mas_top );
        make.left.equalTo( _scrollView.mas_left );
        make.right.equalTo( _scrollView.mas_right );
        make.bottom.equalTo( _scrollView.mas_bottom );

        // match the width of the containerview to the scrollview width:
        make.width.equalTo( _scrollView.mas_width );

        // match the height of the containerview to the intrinsic height of the contentlabel + 100 points for our fixed height title

        // (this is the magical part.)
        make.height.equalTo( _contentLabel.mas_height ).with.offset( 100 );
    }];

    [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {

        // tie the contentlabel edges to the sides of its container:
        make.top.equalTo( _containerView.mas_top ).with.offset(0);
        make.left.equalTo( _containerView.mas_left ).with.offset(0);
        make.right.equalTo( _containerView.mas_right ).with.offset(0);

        // fixed height
        make.height.equalTo( @100 );
    }];

    [_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {

        // tie top edge to the bottom of our title
        make.top.equalTo( _titleLabel.mas_bottom );

        // tie the remaining edges to the sides of the container:
        make.left.equalTo( _containerView.mas_left );
        make.right.equalTo( _containerView.mas_right );
        make.bottom.equalTo( _containerView.mas_bottom );
    }];
}

- (void) viewWillLayoutSubviews
{
    // perform a scrollview layout so the containerView width will be set
    [_scrollView setNeedsLayout];
    [_scrollView layoutIfNeeded];

    // update the preferred layout width of the content label;
    // this affects the label's intrinsicContentSize and will force our constraints to be recalculated
    CGFloat preferredWidth = _containerView.frame.size.width;
    _contentLabel.preferredMaxLayoutWidth = preferredWidth;


    // we don't need this since the scrollview is fully using autolayout to adjust the content-size.  but just to show that it works:

    CGSize fittingSize = [_containerView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];

    NSLog( @"container fitting size: %@", NSStringFromCGSize( fittingSize ));
}

- (NSString*) loremIpsum
{
    return @"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing <br>Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type<br> and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
}

@end

并且,当约束全部正常工作时,这是 systemLayoutSizeFittingSize 的输出:

2013-08-05 15:01:16.309 testLabelConstraints[8265:c07] container fitting size: {721, 6868}

关于iphone - 具有自动布局的 UIView,获取他的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902322/

有关iphone - 具有自动布局的 UIView,获取他的大小的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  6. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  7. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  8. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  9. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  10. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

随机推荐