我正在为我的一个应用程序创建一个自动布局友好的拆分视图类。它的各种特性之一是它可以折叠窗格,并且可以为它们的折叠设置动画,就像你可能看到的 NSSplitView 所做的那样。
由于我正在使用约束,因此我通过在窗格上放置所需的宽度 =(当前宽度)约束,然后以动画方式将约束的常量设置为 0 来实现此目的:
- (NSLayoutConstraint*)newHiddenConstraintAnimated:(BOOL)animated {
NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:NSWidth(self.view.frame)];
constraint.priority = NSLayoutPriorityRequired;
CABasicAnimation * anim = [CABasicAnimation animation];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.duration = 0.2;
constraint.animations = [NSDictionary dictionaryWithObject:anim forKey:@"constant"];
[self.view addConstraint:constraint];
[(animated ? constraint.animator : constraint) setConstant:0.0];
return constraint;
}
这很好用。不幸的是,稍后扩展窗格的效果并不好。
- (void)removeHiddenConstraintAnimated:(BOOL)animated {
if(!animated) {
[self.view removeConstraint:self.hiddenConstraint];
}
else {
NSLayoutConstraint * constraint = self.hiddenConstraint;
NSView * theView = self.view;
[NSAnimationContext beginGrouping];
[constraint.animator setConstant:self.width];
[NSAnimationContext currentContext].completionHandler = ^{
[theView removeConstraint:constraint];
};
[NSAnimationContext endGrouping];
}
self.hiddenConstraint = nil;
}
如果我插入一些计时代码,我可以看到完成处理程序几乎立即触发,在它有时间动画之前移除约束。在 NSAnimationContext 上设置持续时间无效。
知道我在这里做错了什么吗?