【发布时间】:2011-05-10 17:34:34
【问题描述】:
我正在使用带有图像的 UIButton 用于正常和突出显示状态。它们按预期工作,但我希望进行一些淡入淡出/合并过渡,而不仅仅是突然交换。
我该怎么做?
【问题讨论】:
标签: iphone objective-c uibutton
我正在使用带有图像的 UIButton 用于正常和突出显示状态。它们按预期工作,但我希望进行一些淡入淡出/合并过渡,而不仅仅是突然交换。
我该怎么做?
【问题讨论】:
标签: iphone objective-c uibutton
这可以使用 UIView 的过渡动画来完成。 isHighlighted 属性不是可动画的也没关系,因为它会转换整个视图。
UIView.transition(with: button,
duration: 4.0,
options: .transitionCrossDissolve,
animations: { button.isHighlighted = true },
completion: nil)
[UIView transitionWithView:button
duration:4.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{ button.highlighted = YES; }
completion:nil];
【讨论】:
highlighted 属性是可动画的。
highlighted 属性不可动画化,因此必须使用+transitionWithView:duration:options:animations:completion: 而不是+animateWithDuration:delay:options:animations:completion:。
transition(with: UIView...) 不关心属性是否可动画,因为它会转换整个视图。
.transitionCrossDissolve。其他动画样式不能可靠地制作动画。 @MariánČerný - 我建议您扩展此示例,并考虑 where 来执行此操作,例如在... isHighlighted { didSet {} }内部
为了实现这一点,我扩展了 UIButton。添加了一个名为 hilightedImage 的新属性,代码如下:
- (void)setHilightImage:(UIImageView *)_hilightImage
{
if (hilightImage != _hilightImage) {
[hilightImage release];
hilightImage = [_hilightImage retain];
}
[hilightImage setAlpha:0];
[self addSubview:hilightImage];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.14];
if(hilightImage){
[hilightImage setAlpha:1];
}
[UIView commitAnimations];
[super touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
self.highlighted = FALSE;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.14];
if(hilightImage){
[hilightImage setAlpha:0];
}
[UIView commitAnimations];
[super touchesEnded:touches withEvent:event];
}
【讨论】:
UIButton 继承自 UIView
然后你得到它的视图并调用beginAnimations:context:
然后是所有合适的 setAnimation 方法。
UIView 类的以下属性是可动画的:
【讨论】:
这是一个独立的解决方案,它还支持布尔 animated 标志。
- (void)setEnabled:(BOOL)enabled animated:(BOOL)animated
{
if (_button.enabled == enabled) {
return;
}
void (^transitionBlock)(void) = ^void(void) {
_button.enabled = enabled;
};
if (animated) {
[UIView transitionWithView:_button
duration:0.15
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
transitionBlock();
}
completion:nil];
} else {
transitionBlock();
}
}
【讨论】:
@marián-Černý 用 Swift 回答:
斯威夫特 2
UIView.transitionWithView(button,
duration: 4.0,
options: .TransitionCrossDissolve,
animations: { button.highlighted = true },
completion: nil)
Swift 3、4、5
UIView.transition(with: button,
duration: 4.0,
options: .transitionCrossDissolve,
animations: { button.isHighlighted = true },
completion: nil)
【讨论】:
使用 CustomButton 代替 UIButton 并覆盖 isHighlighted 属性对我有用;
class KeypadButton: UIButton {
var highlightDuration: TimeInterval = 0.25
override var isHighlighted: Bool {
didSet {
if oldValue == false && isHighlighted {
highlight()
} else if oldValue == true && !isHighlighted {
unHighlight()
}
}
}
func highlight() {
animateBackground(to: highlightedBackgroundColor, duration: highlightDuration)
}
func unHighlight() {
animateBackground(to: normalBackgroundColor, duration: highlightDuration)
}
private func animateBackground(to color: UIColor?, duration: TimeInterval) {
guard let color = color else { return }
UIView.animate(withDuration: highlightDuration) {
self.backgroundColor = color
}
}
}
【讨论】: