在iOS 7中,我的UIButton标题会在错误的时间(迟到)动画设置。在iOS 6上不会出现此问题。我只是在使用:
[self setTitle:text forState:UIControlStateNormal];
我希望这种情况立即发生,并且没有空白框。这种眨眼特别令人分心,并吸引了其他动画的注意力。
self.button.titleLabel.text = text
。但这不会调整标签框架的大小,并且无法正确使用UIControlStates
在iOS 7中,我的UIButton标题会在错误的时间(迟到)动画设置。在iOS 6上不会出现此问题。我只是在使用:
[self setTitle:text forState:UIControlStateNormal];
我希望这种情况立即发生,并且没有空白框。这种眨眼特别令人分心,并吸引了其他动画的注意力。
self.button.titleLabel.text = text
。但这不会调整标签框架的大小,并且无法正确使用UIControlStates
Answers:
这适用于自定义按钮:
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
对于系统按钮,您需要在重新启用动画之前添加此按钮(感谢@Klaas):
[_button layoutIfNeeded];
[_button layoutIfNeeded];
使用该performWithoutAnimation:
方法,然后强制立即进行布局,而不是稍后进行。
[UIView performWithoutAnimation:^{
[self.myButton setTitle:text forState:UIControlStateNormal];
[self.myButton layoutIfNeeded];
}];
[button layoutIfNeeded];
在块内调用,它适用于系统按钮。
将按钮类型更改为定制表单界面构建器。
这对我有用。
在Swift中,您可以使用:
UIView.performWithoutAnimation {
self.someButtonButton.setTitle(newTitle, forState: .normal)
self.someButtonButton.layoutIfNeeded()
}
layoutIfNeeded()
则该按钮会被标记为需要重绘,但直到下一次布局通过时才会发生,这将在performWithoutAnimation
请注意 :
_button的 “ buttonType ”为“ UIButtonTypeSystem”时,以下代码无效:
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
当_button的 “ buttonType ”为“ UIButtonTypeCustom”时,以上代码有效。
从iOS 7.1开始,唯一适用于我的解决方案是使用type初始化按钮UIButtonTypeCustom
。
所以我找到了可行的解决方案:
_logoutButton.titleLabel.text = NSLocalizedString(@"Logout",);
[_logoutButton setTitle:_logoutButton.titleLabel.text forState:UIControlStateNormal];
首先,我们更改按钮的标题,然后调整此标题的按钮大小
我做了一个Swift扩展来做到这一点:
extension UIButton {
func setTitleWithoutAnimation(title: String?) {
UIView.setAnimationsEnabled(false)
setTitle(title, forState: .Normal)
layoutIfNeeded()
UIView.setAnimationsEnabled(true)
}
}
适用于我在iOS 8和9上运行的UIButtonTypeSystem
。
(用于Swift 2,Swift 3和Objective-C的代码应该相似)
通常,通常只需将按钮类型设置为Custom即可,但是由于其他原因,我需要继承UIButton并将其按钮类型恢复为默认值(系统),因此闪烁再次出现。
UIView.setAnimationsEnabled(false)
更改标题之前先进行设置,然后再更改为true,无论我是否打电话,都无法避免闪烁self.layoutIfNeeded()
。
这,并且仅按照以下确切顺序,才对我适用于iOS 9和10 beta:
1)为UIButton创建一个子类(也不要忘记在Storyboard中为按钮设置自定义类)。
2)覆盖setTitle:forState:
如下:
override func setTitle(title: String?, forState state: UIControlState) {
UIView.performWithoutAnimation({
super.setTitle(title, forState: state)
self.layoutIfNeeded()
})
}
在Interface Builder中,您可以将按钮类型保留为System,而无需将其更改为Custom Type即可使用此方法。
我希望这对其他人有帮助,我已经通过烦人的闪烁按钮苦苦挣扎了很长时间,希望可以避免对其他人使用它;)
layoutIfNeeded()
:]
您可以从标题标签的图层中删除动画:
[[[theButton titleLabel] layer] removeAllAnimations];
我发现该解决方法也可以与UIButtonTypeSystem一起使用,但是仅在由于某种原因启用了按钮的情况下才可以使用。
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
因此,如果需要在设置标题时禁用该按钮,则必须添加这些内容。
[UIView setAnimationsEnabled:NO];
_button.enabled = YES;
[_button setTitle:@"title" forState:UIControlStateNormal];
_button.enabled = NO;
[UIView setAnimationsEnabled:YES];
(iOS 7,Xcode 5)
[_button setTitle:@"title" forState:UIControlStateDisabled]
结合以上很好的答案,将导致以下UIButtonTypeSystem解决方法:
if (_button.enabled)
{
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
}
else // disabled
{
[UIView setAnimationsEnabled:NO];
_button.enabled = YES;
[_button setTitle:@"title" forState:UIControlStateNormal];
_button.enabled = NO;
[UIView setAnimationsEnabled:YES];
}
在UITabBarController的视图控制器中更改按钮标题时遇到了丑陋的动画问题。最初在情节提要中设置的标题会出现一小段时间,然后逐渐淡化为新值。
我想遍历所有子视图,并使用按钮标题作为键来通过NSLocalizedString获取其本地化值,例如;
for(UIView *v in view.subviews) {
if ([v isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton*)v;
NSString *newTitle = NSLocalizedString(btn.titleLabel.text, nil);
[btn setTitle:newTitle];
}
}
我发现触发动画的实际上是对btn.titleLabel.text的调用。因此,为了仍然使用情节提要板并像这样动态地对组件进行本地化,我确保将每个按钮的“还原ID”(在Identity Inspector中)设置为与标题相同,并将其用作键而不是标题。
for(UIView *v in view.subviews) {
if ([v isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton*)v;
NSString *newTitle = NSLocalizedString(btn.restorationIdentifier, nil);
[btn setTitle:newTitle];
}
}
不理想,但是可以。
您实际上可以在动画块外部设置标题,只需确保layoutIfNeeded()
在performWithoutAnimation内部调用即可:
button1.setTitle("abc", forState: .Normal)
button2.setTitle("abc", forState: .Normal)
button3.setTitle("abc", forState: .Normal)
UIView.performWithoutAnimation {
self.button1.layoutIfNeeded()
self.button2.layoutIfNeeded()
self.button3.layoutIfNeeded()
}
如果您有一堆按钮,请考虑仅layoutIfNeeded()
在超级视图上调用:
button1.setTitle("abc", forState: .Normal)
button2.setTitle("abc", forState: .Normal)
button3.setTitle("abc", forState: .Normal)
UIView.performWithoutAnimation {
self.view.layoutIfNeeded()
}
也许生成2个动画和2个按钮是更好的解决方案,以避免动画和更改按钮文本时出现的问题?
我创建了第二个uibutton并生成了2个动画,该解决方案可以正常使用。
_button2.hidden = TRUE;
_button1.hidden = FALSE;
CGPoint startLocation = CGPointMake(_button1.center.x, button1.center.y - 70);
CGPoint stopLocation = CGPointMake(_button2.center.x, button2.center.y- 70);
[UIView animateWithDuration:0.3 animations:^{ _button2.center = stopLocation;} completion:^(BOOL finished){_button2.center = stopLocation;}];
[UIView animateWithDuration:0.3 animations:^{ _button1.center = startLocation;} completion:^(BOOL finished){_button1.center = startLocation;}];
Swift中动画按钮标题更改的便捷扩展,可与默认实现完美配合:
import UIKit
extension UIButton {
/// By default iOS animated the title change, which is not desirable in reusable views
func setTitle(_ title: String?, for controlState: UIControlState, animated: Bool = true) {
if animated {
setTitle(title, for: controlState)
} else {
UIView.setAnimationsEnabled(false)
setTitle(title, for: controlState)
layoutIfNeeded()
UIView.setAnimationsEnabled(true)
}
}
}
UIButton
。