使用Autolayout单击按钮调整UIViews的大小

时间:2014-09-24 15:35:46

标签: ios objective-c ios7

我是Auto布局约束的新手。我的主视图上有2个视图(topView和paintView),以及主视图右上角的按钮。加载视图时,topView占据整个主视图(不包括按钮)。单击该按钮,我希望topView占据主视图的70%,而paintView占用其余部分(不包括按钮)。 我使用storyboard为topView设置了X,Y和top限制。 paintView和相应的约束已经以编程方式设置。

我现在的代码是:

-(void)setupPaintView
{
    UIView *pPaintView = [UIView new];
    [pPaintView setBackgroundColor:[UIColor yellowColor]];
    pPaintView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:pPaintView];
    self.paintView = pPaintView;
    [self addConstraintsToView];
    //[self setTopViewFrame];

}

-(void)addConstraintsToView
{

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.paintView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.topView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]];

    [self.view addConstraint:[NSLayoutConstraint
                              constraintWithItem:self.paintView
                              attribute:NSLayoutAttributeWidth
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.topView
                              attribute:NSLayoutAttributeWidth
                              multiplier:1.0
                              constant:0.0]];

     [self.view addConstraint:[NSLayoutConstraint
                              constraintWithItem:self.topView
                              attribute:NSLayoutAttributeBottom
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.paintView
                              attribute:NSLayoutAttributeTop
                              multiplier:1.0
                              constant:0.0]];


    NSLayoutConstraint *pHeightConstraintTopView = [NSLayoutConstraint
                                             constraintWithItem:self.topView
                                             attribute:NSLayoutAttributeHeight
                                             relatedBy:NSLayoutRelationEqual
                                             toItem:self.view
                                             attribute:NSLayoutAttributeHeight
                                             multiplier:1.0
                                             constant:0.0];

    self.heightconstraintTopView = pHeightConstraintTopView;

    [self.view addConstraint:pHeightConstraintTopView];


    NSLayoutConstraint *pHeightConstraintPaintView = [NSLayoutConstraint
                                                    constraintWithItem:self.paintView
                                                    attribute:NSLayoutAttributeHeight
                                                    relatedBy:NSLayoutRelationEqual
                                                    toItem:self.view
                                                    attribute:NSLayoutAttributeHeight
                                                      multiplier:0.0
                                                    constant:0.0];

    self.heightconstraintPaintView = pHeightConstraintPaintView;

    [self.view addConstraint:pHeightConstraintPaintView];

}

在按钮上单击以下方法:

-(IBAction)detailBtnClick:(id)sender
{
    if(self.heightconstraintPaintView.constant == 0)
    {

        self.heightconstraintTopView.constant = 0.7*self.view.frame.size.height;
        self.heightconstraintPaintView.constant = 0.3*self.view.frame.size.height;
        [self.view setNeedsUpdateConstraints];
    }
    else
    {
        self.heightconstraintTopView.constant = self.view.frame.size.height;
        self.heightconstraintPaintView.constant = 0;
        [self.view setNeedsUpdateConstraints];
    }

}

当视图加载时,topView会获取主视图的高度,这是此处所需的。但是当我点击按钮时,topView保持100%,即它不会调整大小,paintView也不会。我正在修改topView和paintView约束的常量属性,但我不确定这是正确的方法。这里的约束是必须仅使用Autolayout约束来布局视图。如何通过单击按钮调整视图大小? 欢迎任何帮助。

感谢timothykc和其他人,我已经成功地解决了上述问题。但我现在面临另一个问题。当我将模拟器的方向更改为横向时,paintView几乎保持隐藏状态。以下是代码(toggle是一个布尔值,决定是否拉伸/缩小视图):

-(IBAction)detailBtnClick:(id)sender
{


        if(self.toggle == FALSE)
        {
            self.topViewHeightConstraint.constant = 0.7*self.bounds.frame.size.height;
            self.heightconstraintPaintView.constant = 0.3*self.bounds.frame.size.height;

            //[self.view layoutIfNeeded];
        }
        else
        {
            self.topViewHeightConstraint.constant = self.view.bounds.size.height;
            self.heightconstraintPaintView.constant = 0;
            //[self.view layoutIfNeeded];

        }

    self.toggle = !self.toggle;


}

topViewHeightConstraint已添加为属性,如timothykc所示。这对于纵向方向正常工作,但对于横向不正常,因为topView的高度不会根据需要改变(70%),这意味着比率未得到正确处理。

3 个答案:

答案 0 :(得分:0)

要获得视图更新的约束,您需要在要更新的任何约束上设置新常量后调用[self.view layoutIfNeeded];而不是[self.view setNeedsUpdateConstraints];

答案 1 :(得分:0)

我将提供一个故事板驱动的解决方案,可以帮助您解决其他自动布局问题。

我对您的具体问题的解决方案,您有两个观点(下图中的1和2):

对于视图1,将视图固定在superview的左侧,顶部和右侧。然后 设置一个高度不变。 (例如568,iphone 5s的全高)

对于视图2,将其固定在superview的左侧,底部和右侧。然后 将其固定到视图1的底部。

打开助理编辑器视图,这是关键技巧 - 将视图1上的高度限制转换为VC上的nslayoutconstraint属性 。您可以通过查找约束,然后控制拖动到VC来执行此操作。 (e.g.`


@property(强,非原子)IBOutlet NSLayoutConstraint * viewHeight;`


现在,您可以使用链接到按钮的操作来操作此属性,例如

- (IBAction)scale:(id)sender {
    self.viewHeight.constant = 397.6; //%70 of 568....
}

在我的示例中,我手动将nslayoutconstraint.CONSTANT更改为任意值。

要了解发生了什么,您需要知道自动布局是一种确定任何布局对象(x坐标,坐标,宽度,高度)的方法。当xcode无法确定所有4个值时发生警告......

在视图1中,我们给出了高度约束。从超视图的距离外推X,Y和宽度。 (如果左边和右边的东西是0,那么宽度填满整个屏幕......;如果从顶部和左边0,那么坐标必须是(0,0))

在视图2中,X必须为0,因为距离左边是0.宽度全屏...高度和Y根据视图1的高度外推!

因此,当我们在视图1中混淆高度约束时,它会影响视图2的高度和Y坐标!

constraint overview

答案 2 :(得分:0)

实际上这更多是关于我的方法的评论,但我决定将其作为答案发布,因为首先,这解决了我的问题,其次,它涉及一些代码片段,在评论部分很难阅读。关于编辑中提到的方向问题,我提出了一种解决方法,以适应关于切换按钮和方向更改的视图恢复要求。用于此目的的三种方法是: 在按钮单击事件上调用以下方法。

-(IBAction)detailBtnClick:(id)sender
{
    [self updateViewConstraints:self.toggle];
    self.toggle = !self.toggle;

}

以下方法更新约束。

-(void)updateViewConstraints :(BOOL)toggleValue
{
    if(toggleValue == FALSE)
    {
        self.topViewHeightConstraint.constant = 0.7*self.view.bounds.size.height;
        self.heightconstraintPaintView.constant = 0.3*self.view.bounds.size.height;
    }
    else
    {
        self.topViewHeightConstraint.constant = self.view.bounds.size.height;
        self.heightconstraintPaintView.constant = 0;
    }
}

以下方法调用上述方法以在方向更改时更新约束:

-(void)viewWillLayoutSubviews
{
            [self updateViewConstraints:!self.toggle];
}