Programming

타이틀 변경시 원하지 않는 UIButton 애니메이션을 중지하는 방법은 무엇입니까?

procodes 2020. 5. 10. 11:48
반응형

타이틀 변경시 원하지 않는 UIButton 애니메이션을 중지하는 방법은 무엇입니까?


iOS 7에서 UIButton 타이틀이 잘못된 시간에 늦게 애니메이션으로 움직이고 있습니다. 이 문제는 iOS 6에는 나타나지 않습니다.

[self setTitle:text forState:UIControlStateNormal];

나는 이것이 빈 프레임없이 즉시 발생하는 것을 선호합니다. 이 깜박임은 특히주의를 산만하게하며 다른 애니메이션에서주의를 끕니다.


이것은 사용자 정의 버튼에서 작동합니다.

[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

시스템 버튼의 경우 애니메이션을 다시 활성화하기 전에 이것을 추가해야합니다 (@Klaas 감사).

[_button layoutIfNeeded];

performWithoutAnimation:방법을 사용하여 나중에 대신 즉시 레이아웃을 강제 실행 하십시오 .

[UIView performWithoutAnimation:^{
  [self.myButton setTitle:text forState:UIControlStateNormal];
  [self.myButton layoutIfNeeded];
}];

버튼 유형을 사용자 정의 양식 인터페이스 빌더로 변경하십시오.

여기에 이미지 설명을 입력하십시오

이것은 나를 위해 일했습니다.


Swift에서는 다음을 사용할 수 있습니다.

UIView.performWithoutAnimation {
    self.someButtonButton.setTitle(newTitle, forState: .normal)
    self.someButtonButton.layoutIfNeeded()
}

참고 :

_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];

먼저 버튼의 제목을 변경 한 다음이 제목의 버튼 크기를 조정하십시오.


버튼 유형을 UIButtonTypeCustom으로 설정하면 깜박임이 멈 춥니 다.


이 작업을 수행하기 위해 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 용입니다.)


UIButton 유형을 Custom으로 설정하십시오. 페이드 인 / 아웃 애니메이션을 제거해야합니다.


당신은 단순히 사용자 정의 버튼을 만들 수 있으며 제목을 변경하는 동안 애니메이션이 중지됩니다.

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitle:@"the title" forState:UIControlStateNormal];

스토리 보드 확인란에서 할 수 있습니다 : 스토리 보드에서 버튼을 선택하십시오-> 속성 관리자 (왼쪽에서 네 번째)를 선택하십시오-> '유형'드롭 다운 메뉴에서 '시스템'대신 '사용자 정의'를 선택하십시오. .

행운을 빕니다!


일반적으로 단순히 버튼 유형을 사용자 정의로 설정하면 나에게 적합하지만 다른 이유로 UIButton을 서브 클래스 화하고 버튼 유형을 기본값 (시스템)으로 다시 설정해야 깜박임이 다시 나타납니다.

UIView.setAnimationsEnabled(false)제목을 변경 하기 전에 설정 한 다음 다시 true로 설정 하면 전화했는지 여부에 관계없이 깜박 거리지 self.layoutIfNeeded()않습니다.

이것은 iOS 9 및 10 베타에서 다음과 같은 순서로만 작동했습니다.

1) UIButton에 대한 서브 클래스를 작성하십시오 (스토리 보드에서도 버튼에 대한 사용자 정의 클래스를 설정하는 것을 잊지 마십시오).

2) Override setTitle:forState: as follows:

override func setTitle(title: String?, forState state: UIControlState) {

    UIView.performWithoutAnimation({

        super.setTitle(title, forState: state)

        self.layoutIfNeeded()
    })
}

In Interface Builder, you can leave the button type to System, no need to change it to Custom Type for this approach to work.

I hope this helps someone else, I've struggled for so long with the annoying blinking buttons that I hope to avoid it to others ;)


You can remove the animations from from the title label's layer:

    [[[theButton titleLabel] layer] removeAllAnimations];

Swift 4 version of Xhacker Liu answer

import Foundation
import UIKit
extension UIButton {
    func setTitleWithOutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
} 

Swift 5

myButton.titleLabel?.text = "title"
myButton.setTitle("title", for: .normal)

I've found that this workaround works with UIButtonTypeSystem as well but will only work if the button is enabled for some reason.

[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

So you'll have to add these if you need the button to be disabled when setting its title.

[UIView setAnimationsEnabled:NO];
_button.enabled = YES;
[_button setTitle:@"title" forState:UIControlStateNormal];
_button.enabled = NO;
[UIView setAnimationsEnabled:YES];

(iOS 7, Xcode 5)


Combining above great answers results in following workaround for 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];
}

I got the ugly animation problem when changing button titles in view controllers within a UITabBarController. The titles that were originally set in the storyboard showed up for a short while before fading into their new values.

I wanted to iterate through all subviews and use the button titles as keys to get their localized values with NSLocalizedString, such as;

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];
    }

}

I found out that what's triggering the animation is really the call to btn.titleLabel.text. So to still make use of the storyboards and have the components dynamically localized like this I make sure to set every button's Restoration ID (in Identity Inspector) to the same as the title and use that as key instead of the title;

for(UIView *v in view.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {
        UIButton *btn = (UIButton*)v;
        NSString *newTitle = NSLocalizedString(btn.restorationIdentifier, nil);
        [btn setTitle:newTitle];
    }

}

Not ideal, but works..


You can actually set the title outside of an animation block, just be sure to call layoutIfNeeded() inside a 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()
}

If you have a bunch of buttons, consider just calling layoutIfNeeded() on the super view:

button1.setTitle("abc", forState: .Normal)
button2.setTitle("abc", forState: .Normal)
button3.setTitle("abc", forState: .Normal)
UIView.performWithoutAnimation {
    self.view.layoutIfNeeded()
}

The Xhacker Liu extension converted to Swift 3 :

extension UIButton {
    func setTitleWithoutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

Maybe generating 2 animations and 2 buttons is a better solution, to avoid the problem that is appearing with animating and changing the text of a button?

I created a second uibutton and generated 2 animation, this solution works with no hickups.

    _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;}];

I got it to work with a combination of answers:

[[[button titleLabel] layer] removeAllAnimations];

    [UIView performWithoutAnimation:^{

        [button setTitle:@"Title" forState:UIControlStateNormal];

    }];

A convenient extension for animated button title change in Swift that plays nicely with the default implementation:

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)
    }
  }
}

참고URL : https://stackoverflow.com/questions/18946490/how-to-stop-unwanted-uibutton-animation-on-title-change

반응형