16

プログラムでコンテンツが取り込まれた UIView ウィッチが 1 つあります。この UIView のレイアウトは Auto-layout を使用して作成されます。

このビューは、1 つの UIScrollView のサブビューである必要があり、垂直方向にスクロールする必要があります。

次のようなコードがあります。

// 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

//更新

OK、この UILabel を self.content に追加しました。これは UIView で作成されたものです。[[UIView alloc] initWithFrame:CGRectMake(self.layoutMargin, self.layoutMargin, 1024 - self.layoutMargin*2, 100)]);

この self.content ビューは、私にとって単なるコンテナであり、いくつかの に配置する必要がありますUIScrollView。の contentSize を設定するには、self.content の高さが必要ですUIScrollView

[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);

これはログです: サイズ: 17713.000000 0.000000

次のようになります: http://d.pr/i/Rxku

4

3 に答える 3

40

sizeToFit自動レイアウトを使用している場合、使用する API は間違っています。

自動レイアウトに使用する正しい API はUIView systemLayoutSizeFittingSize: です。ほとんどの場合、 を渡しUILayoutFittingCompressedSizeます。これは、指定された制約でビューをバインドできる最小サイズである CGSize を返します。

このリンクを確認してください

編集:投稿された追加のコードに応じて...

Masonryライブラリを 使用したことはありませんが、すばらしいです。

UILabelsintrinsicContentSizeテキストを表示するのに十分な大きさの を提供します。複数行テキストのこのサイズを計算するために、ラベルは、固定される単一の寸法を知る必要があり、それはpreferredMaxLayoutWidthプロパティを介した望ましい幅の寸法です。値を指定しないpreferredMaxLayoutWidth場合 (デフォルトは 0)、ラベルは、1 行のテキストをレイアウトする場合のように、固有のコンテンツ サイズを計算します。

あなたのコードでは、ラベルを決して設定しないpreferredMaxLayoutWidthので、ラベルのintrinsicContentSizeに依存する自動レイアウトによって実行されるレイアウトは、あなたが期待するものではありません.

私はあなたのコードを取り出して、それを新しい例にまとめました。これをコピーして、クリーンなビューコントローラーのサブクラスに貼り付けることができます。

#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}
于 2013-07-31T01:29:00.063 に答える
-1

試しましたKVOか?

viewDidLoadオブザーバーを追加します。

[contentView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionPrior context:NULL];

次に、このメソッドを追加します。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"frame"]) {
        CGRect oldFrame = CGRectNull;
        CGRect newFrame = CGRectNull;
        if([change objectForKey:@"old"] != [NSNull null]) {
            oldFrame = [[change objectForKey:@"old"] CGRectValue];
        }
        if([object valueForKeyPath:keyPath] != [NSNull null]) {
            newFrame = [[object valueForKeyPath:keyPath] CGRectValue];
        }
        //new size!
        if (newFrame.size.width > 0 && newFrame.size.height > 0) {
            NSLog(@"%@", NSStringFromCGRect(newFrame));
        }
    }
}

contentViewこれは、より大きなものに設定されているときのフレームを出力する必要がありますCGSize(1,1)

于 2013-08-02T07:00:49.267 に答える