我有两个这样的观点:
我设置了垂直空间约束:
如您所见,BottomView顶部和TopView底部之间的约束为0.但遗憾的是,当我点击切换按钮移动时,它不正确顶视图。这是代码:
@IBAction func onToggle(sender: AnyObject) {
self.topView.transform = CGAffineTransformMakeTranslation(0, -self.topView.bounds.height)
}
即使我添加:
,它也是一样的 self.view.setNeedsUpdateConstraints()
self.view.setNeedsLayout()
结果是:
显然,TopView的底部和BottomView顶部之间的边距不是0.自动布局不起作用。我错过了什么吗?感谢
P.S。:我知道还有另一种方法可以解决这个问题。例如,在按下切换按钮时更改BottomView的框架。但我的问题是为什么自动布局不像我期望的那样工作?
答案 0 :(得分:1)
似乎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];
}
你得到了红色的平滑折叠动画:
答案 1 :(得分:1)
我认为它可能与TopView的约束有关。将translate转换应用于顶视图时,TopView的框架已更改。因此它的最高边际约束也发生了变化。这将影响底部视图的上边距约束。
我的建议是不要为UIView应用翻译变换。而是更改顶视图的顶部垂直空间约束。
self.topConstraint.constant = -self.topView.bounds.height
底部视图将以这种方式跟随顶视图。这意味着自动布局确实有效。希望它会有所帮助。
答案 2 :(得分:0)
在完成其余布局代码后,将应用视图上的转换。这包括自动布局,因此如果您更改视图的变换,它将不会影响自动布局。转换将相对于自动布局放置视图的位置。