iOS中的Autolayout问题

时间:2013-08-17 11:15:46

标签: ios autolayout

我在UIView类型的容器视图中有一个标签,图像和按钮。容器视图再次是UIView类型的超级容器视图的子视图。所有布局都是使用自动布局可视格式语言在代码中完成的。我想要实现的是在按下按钮时移除标签并期望超级容器调整其内容的大小。但目前发生的是整个超级容器从屏幕上消失。有人能告诉我为什么会这样吗?附件是我的代码示例。

- (void)viewDidLoad {
    [super viewDidLoad];


    superContainer = [[UIView alloc] initWithFrame:CGRectZero];
    superContainer.backgroundColor = [UIColor orangeColor];

    [self.view addSubview:superContainer];


    Container = [[UIView alloc] initWithFrame:CGRectZero];
    Container.backgroundColor = [UIColor redColor];

    [superContainer addSubview:Container];

    NSDictionary *sViews = NSDictionaryOfVariableBindings(Container);

    [superContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10.0-[Container]-10.0-|" options:0 metrics:nil views:sViews]];

    [superContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10.0-[Container]-10.0-|" options:0 metrics:nil views:sViews]];


    CGSize temp1 = [superContainer systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];


    superContainer.frame = CGRectMake(superContainer.frame.origin.x, superContainer.frame.origin.y, temp1.width, temp1.height);


    closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    //[closeButton setImage: forState:UIControlStateNormal];
    [closeButton setBackgroundImage:[UIImage imageNamed:@"closebox.png"] forState:UIControlStateNormal];
    [closeButton addTarget:self action:@selector(hide:) forControlEvents:UIControlEventTouchUpInside];
    NSLog(@"Close button frame is %@",NSStringFromCGRect(closeButton.frame));
    //closeButton.frame = CGRectMake(0, 10, 32, 32);
    [Container addSubview:closeButton];


    helpLabel = [[UILabel alloc] init];
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text. "];
    helpLabel.attributedText = attrString;


    helpLabel.numberOfLines = 0;
    helpLabel.backgroundColor = [UIColor greenColor];
    [Container addSubview:helpLabel];


    helpImageView = [[UIImageView alloc] init];
    helpImageView.image = [UIImage imageNamed:@"testimage.png"];
    NSLog(@"frame of imageview is %@",NSStringFromCGRect(helpImageView.frame));
    [Container addSubview:helpImageView];

    dismissButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];
    [[dismissButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
    dismissButton.backgroundColor = [UIColor blueColor];
    [Container addSubview:dismissButton];

    [Container setClipsToBounds:YES];

    [self addAutoLayoutProperties];

    NSDictionary *views = NSDictionaryOfVariableBindings(helpLabel,helpImageView,dismissButton,closeButton);

    NSDictionary *metrics = @{@"buttonHeight":@32.0};

    // Horizontal layout - for helplabel
    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5.0-[helpLabel(400)]-5.0-|" options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight metrics:metrics views:views]];
    // Horizontal layout - for helpImageView
    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[helpImageView]|" options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight metrics:metrics views:views]];
    // Horizontal layout - for dismissButton
    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[dismissButton]-|" options:NSLayoutFormatAlignAllCenterX|NSLayoutFormatAlignAllCenterY metrics:metrics views:views]];
    // Horizontal layout - for dismissButton
    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[closeButton]-1.0-|" options:0 metrics:metrics views:views]];

    // Vertical layout

    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-1.0-[closeButton]" options:0 metrics:metrics views:views]];

    [Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-buttonHeight-[helpLabel]-5.0-[helpImageView]-5.0-[dismissButton]-5.0-|" options:0 metrics:metrics views:views]];

    CGSize temp = [Container systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];


    Container.frame = CGRectMake(Container.frame.origin.x, Container.frame.origin.y, temp.width, temp.height);

    superContainer.center = self.view.center;

}

添加自动布局属性的方法

-(void)addAutoLayoutProperties {
    helpLabel.translatesAutoresizingMaskIntoConstraints = NO;
    helpImageView.translatesAutoresizingMaskIntoConstraints = NO;
    dismissButton.translatesAutoresizingMaskIntoConstraints = NO;
    closeButton.translatesAutoresizingMaskIntoConstraints = NO;

    superContainer.translatesAutoresizingMaskIntoConstraints = NO;
    Container.translatesAutoresizingMaskIntoConstraints = NO;
}

我删除标签的方法。

- (IBAction)removeASubview:(id)sender {

    [helpLabel removeFromSuperview];

}

还有一个问题。从相关视图中删除相关视图时,约束对象会发生什么。它们存在于那里还是被删除了?

1 个答案:

答案 0 :(得分:1)

您可以添加在没有helpLabel及其约束的情况下应该应用的另一个约束,但是为新的约束赋予较低的优先级,以便在存在helpLabel时,其约束将被控制视图,但删除helpLabel后,新约束将发挥作用。 e.g:

[container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-buttonHeight@500-[helpImageView]" options:0 metrics:metrics views:views]];

顺便说一句,如果您希望在删除helpLabel后查看您的观看结果,请使用调试器运行应用,点按暂停按钮(pause)以暂停该应用,在(lldb)调试器提示符下,键入以下命令:

po [[UIWindow keyWindow] recursiveDescription]

请注意,有时候很难确定哪个窗口是哪个窗口,因此我会经常为各种视图提供唯一的数字tag属性,以便更轻松。

此外,在同一命令行中,您可以使用以下命令来识别约束中的模糊布局:

po [[UIWindow keyWindow] _autolayoutTrace]