在 macOS objective-c 上为 NSView 约束(图层支持视图)设置动画
Animate NSView constraints (layer backed view) on macOS objective-c
我在 XCode 12,macOS,objective-c,而不是 iOS。
我有一个包含 3 个项目的菜单(水平堆栈视图):
蓝色下划线是通过编程方式创建的:
- (void)viewDidLoad {
[super viewDidLoad];
[self createAnimatedLineAtButton:self.importButton];
}
// Create line
- (void)createAnimatedLineAtButton:(NSButton*)button {
// This view is layer backed
SHViewCustomBackground* underlineView = [[SHViewCustomBackground alloc] init];
underlineView.backgroundColor = [NSColor colorNamed:@"color_spot"]; // blue color
underlineView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:underlineView];
self.underlineView = underlineView;
[self updateAnimatedLineUnderButton:self.importButton];
}
接下来的代码更新约束(最初调用上面的行创建),然后单击每个按钮。
- (void)updateAnimatedLineUnderButton:(NSButton *)button {
// Constraints are stored here
if (self.underlineConstraints) {
[self.view removeConstraints:self.underlineConstraints];
}
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
context.duration = 1;
context.allowsImplicitAnimation = YES;
NSView* underlineView = self.underlineView;
NSDictionary *views = NSDictionaryOfVariableBindings(underlineView, button);
self.underlineConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[underlineView(1)]" options:NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing metrics:nil views:views];
[self.view addConstraints:self.underlineConstraints];
[self.view layoutSubtreeIfNeeded];
} completionHandler:nil];
}
这是按钮操作
- (IBAction)buttonClicked:(id)sender {
[self updateAnimatedLineUnderButton:(NSButton*)sender];
}
现在我的问题是:当我按“导入”>“导出”>“导入”顺序单击按钮时,该行按预期从导入到导出并返回动画。每当我单击“占位符”(中间按钮)时,该行就会跳动并且不会设置动画。当我之后点击“导入”或“导出”时,它也会跳转。
我正在琢磨这里出了什么问题。所有按钮都正确连接,所有动作都正确触发。
编辑:比较所有按钮后,我发现导入和导出按钮(有效的地方)具有相同的宽度。
这是一个想法……行得通。最初我打算按照你的方式去做,但你可能不喜欢这样,最终动画化了两个约束。但效果很好。
这个想法与您的想法非常相似,但不同之处在于我创建了前导和尾随约束并为其设置了动画。
@implementation ViewController
- ( void ) viewDidLoad
{
super.viewDidLoad;
[self animateLine:self.longButton];
}
// Animate the line
- ( void ) animateLine:( NSButton * ) button
{
[NSAnimationContext runAnimationGroup: ^ ( NSAnimationContext * context ) {
context.duration = 1;
context.allowsImplicitAnimation = YES;
self.leadingConstraint.animator.constant = button.frame.origin.x;
self.trailingConstraint.animator.constant = self.stackView.bounds.size.width - button.frame.origin.x - button.frame.size.width;
NSLog ( @"Setting leading to %f trailing to %f", self.leadingConstraint.constant, self.trailingConstraint.constant );
self.lineField.layoutSubtreeIfNeeded;
}];
}
- ( IBAction ) buttonAction:( id ) sender
{
[self animateLine:sender];
}
就是这样。其余的发生在情节提要中。我设置了约束,以便通过交换第一项和第二项的味道来使距离有意义。
我在 XCode 12,macOS,objective-c,而不是 iOS。
我有一个包含 3 个项目的菜单(水平堆栈视图):
蓝色下划线是通过编程方式创建的:
- (void)viewDidLoad {
[super viewDidLoad];
[self createAnimatedLineAtButton:self.importButton];
}
// Create line
- (void)createAnimatedLineAtButton:(NSButton*)button {
// This view is layer backed
SHViewCustomBackground* underlineView = [[SHViewCustomBackground alloc] init];
underlineView.backgroundColor = [NSColor colorNamed:@"color_spot"]; // blue color
underlineView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:underlineView];
self.underlineView = underlineView;
[self updateAnimatedLineUnderButton:self.importButton];
}
接下来的代码更新约束(最初调用上面的行创建),然后单击每个按钮。
- (void)updateAnimatedLineUnderButton:(NSButton *)button {
// Constraints are stored here
if (self.underlineConstraints) {
[self.view removeConstraints:self.underlineConstraints];
}
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
context.duration = 1;
context.allowsImplicitAnimation = YES;
NSView* underlineView = self.underlineView;
NSDictionary *views = NSDictionaryOfVariableBindings(underlineView, button);
self.underlineConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-[underlineView(1)]" options:NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing metrics:nil views:views];
[self.view addConstraints:self.underlineConstraints];
[self.view layoutSubtreeIfNeeded];
} completionHandler:nil];
}
这是按钮操作
- (IBAction)buttonClicked:(id)sender {
[self updateAnimatedLineUnderButton:(NSButton*)sender];
}
现在我的问题是:当我按“导入”>“导出”>“导入”顺序单击按钮时,该行按预期从导入到导出并返回动画。每当我单击“占位符”(中间按钮)时,该行就会跳动并且不会设置动画。当我之后点击“导入”或“导出”时,它也会跳转。
我正在琢磨这里出了什么问题。所有按钮都正确连接,所有动作都正确触发。
编辑:比较所有按钮后,我发现导入和导出按钮(有效的地方)具有相同的宽度。
这是一个想法……行得通。最初我打算按照你的方式去做,但你可能不喜欢这样,最终动画化了两个约束。但效果很好。
这个想法与您的想法非常相似,但不同之处在于我创建了前导和尾随约束并为其设置了动画。
@implementation ViewController
- ( void ) viewDidLoad
{
super.viewDidLoad;
[self animateLine:self.longButton];
}
// Animate the line
- ( void ) animateLine:( NSButton * ) button
{
[NSAnimationContext runAnimationGroup: ^ ( NSAnimationContext * context ) {
context.duration = 1;
context.allowsImplicitAnimation = YES;
self.leadingConstraint.animator.constant = button.frame.origin.x;
self.trailingConstraint.animator.constant = self.stackView.bounds.size.width - button.frame.origin.x - button.frame.size.width;
NSLog ( @"Setting leading to %f trailing to %f", self.leadingConstraint.constant, self.trailingConstraint.constant );
self.lineField.layoutSubtreeIfNeeded;
}];
}
- ( IBAction ) buttonAction:( id ) sender
{
[self animateLine:sender];
}
就是这样。其余的发生在情节提要中。我设置了约束,以便通过交换第一项和第二项的味道来使距离有意义。