Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 约束条件不为';I don’我没料到会这样_Ios_Swift_Autolayout_Nslayoutconstraint - Fatal编程技术网

Ios 约束条件不为';I don’我没料到会这样

Ios 约束条件不为';I don’我没料到会这样,ios,swift,autolayout,nslayoutconstraint,Ios,Swift,Autolayout,Nslayoutconstraint,我有两种看法: 我设置垂直空间约束: 如您所见,BottomView的顶部和TopView的底部之间的约束为0。但不幸的是,当我单击切换按钮移动顶视图时,情况并非如此。代码如下: @IBAction func onToggle(sender: AnyObject) { self.topView.transform = CGAffineTransformMakeTranslation(0, -self.topView.bounds.height) } 即使我加上: self

我有两种看法:

我设置垂直空间约束:

如您所见,BottomView的顶部和TopView的底部之间的约束为0。但不幸的是,当我单击切换按钮移动顶视图时,情况并非如此。代码如下:

@IBAction func onToggle(sender: AnyObject) {

    self.topView.transform = CGAffineTransformMakeTranslation(0, -self.topView.bounds.height)
}
即使我加上:

    self.view.setNeedsUpdateConstraints()
    self.view.setNeedsLayout()
结果是:

显然,俯视图底部和俯视图顶部之间的边距不是0。自动布局不起作用。我错过什么了吗?谢谢


p.S.:我知道还有另一种方法可以解决这个问题。例如,在按下切换时更改底部视图的框架。但我的问题是,为什么自动布局不能像我预期的那样工作?

视图上的转换在布局代码的其余部分完成后应用。这包括自动布局,因此,如果更改视图的变换,将不会影响自动布局。转换将与自动布局放置视图的位置相关。

似乎iOS 8存在调整UILabel高度约束的错误

无论如何,假设您的两个视图不是UILabel,我建议使用的方法是创建一个属性来记住俯视图的高度约束:

@interface ViewController : UIViewController

@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UIView *bottomView;

// -----------------------------------------------------------
// We will animate this NSLayoutConstraint's constant value
// -----------------------------------------------------------
@property (nonatomic, strong) NSLayoutConstraint *topViewHeightConstraint;

@end
然后设置视图和切换按钮:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self initViews];
    [self initConstraints];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)initViews
{
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.navigationController.navigationBar.translucent = NO;

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Toggle" style:UIBarButtonItemStylePlain target:self action:@selector(toggleTopView)];

    self.topView = [[UIView alloc] init];
    self.topView.backgroundColor = [UIColor colorWithRed:203.0/255.0 green:89.0/255.0 blue:91.0/255.0 alpha:1.0];

    self.bottomView = [[UIView alloc] init];
    self.bottomView.backgroundColor = [UIColor colorWithRed:103.0/255.0 green:167.0/255.0 blue:187.0/255.0 alpha:1.0];

    [self.view addSubview:self.topView];
    [self.view addSubview:self.bottomView];
}

-(void)initConstraints
{
    self.topView.translatesAutoresizingMaskIntoConstraints = NO;
    self.bottomView.translatesAutoresizingMaskIntoConstraints = NO;

    self.topView.layoutMargins = UIEdgeInsetsZero;
    self.bottomView.layoutMargins = UIEdgeInsetsZero;

    id views = @{
                 @"topView": self.topView,
                 @"bottomView": self.bottomView
                 };

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topView]|" options:0 metrics:nil views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomView]|" options:0 metrics:nil views:views]];


    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topView][bottomView]|" options:0 metrics:nil views:views]];

    self.topViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self.topView
                                                                attribute:NSLayoutAttributeHeight
                                                                relatedBy:NSLayoutRelationEqual toItem:nil
                                                                attribute:NSLayoutAttributeHeight
                                                               multiplier:1.0 constant:170.0];

    [self.view addConstraint:self.topViewHeightConstraint];
}

-(void)toggleTopView
{
    if(self.topViewHeightConstraint.constant != 0)
    {
        self.topViewHeightConstraint.constant = 0;
    }
    else
    {
        self.topViewHeightConstraint.constant = 170.0;
    }

    [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{

        [self.view layoutIfNeeded];

    } completion:nil];


}
首先,你会发现:

然后,当您点击切换按钮时,我们将heightConstraint属性常量设置为0:

-(void)toggleTopView
{
    if(self.topViewHeightConstraint.constant != 0)
    {
        self.topViewHeightConstraint.constant = 0;
    }
    else
    {
        self.topViewHeightConstraint.constant = 170.0;
    }

    [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{

        [self.view layoutIfNeeded];

    } completion:nil];
}
您将获得红色的平滑折叠动画:


我认为这可能与TopView的限制有关。将“平移”变换应用于俯视图时,俯视图的框架已更改。所以它的上边距限制也改变了。这将影响底部视图的上边距约束

我的建议是不要对UIView应用translate转换。而是更改顶视图的顶部垂直空间约束

    self.topConstraint.constant = -self.topView.bounds.height

底视图将以这种方式跟随顶视图。这意味着自动布局实际上可以工作。希望能有所帮助。

谢谢。我使用相同的方法创建动画。