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


211

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

[self setTitle:text forState:UIControlStateNormal];

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


우리도 이것을 경험하고 있습니다. iOS7 버그인지 또는 수정해야 할 것인지 확실하지 않습니다.
Sway

시도, [self.button setHighlighted : NO];
karthika

이 아이디어에 감사드립니다. 나는 setHighlighted : NO를 시도했지만 거기에는 운이 없다. setTitle을 내부에 배치하여 깜박임을 줄일 수 있습니다. [UIView animateWithDuration : 0.0f animations : ^ {...}];
exsulto

1
경우에 따라이 해결 방법을 사용할 수 있습니다 self.button.titleLabel.text = text.. 그러나 이것은 레이블 프레임의 크기를 조정하지 않으며 UIControlStates에서 올바르게 작동하지 않습니다.
zxcat

그것은 영리한 해결 방법입니다. 나는 이것을 가지고 놀고 불행히도 UIControlStates를 사용하고있는 것을 볼 것이다.
exsulto

답변:


165

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

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

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

[_button layoutIfNeeded];

12
불행히도 이것은 작동하지 않는 것 같습니다. PerformWithoutAnimation
Sway

9
좋아, 결국 작동했던 수정은 원래 UIButton 텍스트를 비워 두어 코드로 설정할 때 애니메이션을 트리거하지 않도록했습니다.
Sway

27
이 답변에 따라 버튼 유형을 사용자 정의로 설정 한 경우에만 작동합니다 . stackoverflow.com/a/20718467/62 .
Liron Yahdav 1

15
iOS 7.1부터 추가해야했습니다[_button layoutIfNeeded];
Klaas

6
@LironYahdav 버튼 유형이 UIButtonTypeCustom으로 설정되어 있으면이 답변이 필요하지 않습니다.
DonnaLea

262

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

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

11
이것은 받아 들일 수있는 대답뿐만 아니라 작동하지만 더 캡슐화되어 있기 때문에 더 좋아 보입니다. [UIView setAnimationsEnabled : YES]를 추가하거나 트랙에서 제거하는 것을 잊을 수 없습니다.
siburb

19
[button layoutIfNeeded];블록 내부 를 호출하면 시스템 버튼에서 작동합니다 .
Alexandre Blin

1
BTW, 시스템 버튼의 경우 텍스트가 변경된 layoutIfNeed를 호출해야 함
Yon

이것이 최고의 솔루션입니다! 건배
sachadso

이것은 나에게 맞는 것입니다. 6 위에 가장 많이 투표되었습니다. 니스 ...
solgar

79

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

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

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


6
최고의 솔루션! 감사합니다.
Thomás Calmon

3
그러나 이것은 또한 클릭 버튼의 애니메이션을 비활성화합니다. 버튼 표시시 애니메이션 만 비활성화하고 싶습니다.
Piotr Wasilewicz

버튼을 눌렀을 때 애니메이션에 신경 쓰지 않으면 작동합니다.
Joaquin Pereira

나는 이와 같은 두 개의 버튼을 설정했으며 분명히 이것은 내 경우에 가장 우아한 대답입니다. 감사합니다!
Zoltán

79

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

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

1
이것은 지금까지 가장 쉬운 방법이었습니다. 신속한 답변 btw
simplexity

1
스위프트에 대한 최고의 답변!
Nubaslon

화면 밖에서 UIButton 제목을 변경하면 interactivePopGestureRecognizer로 이상한 애니메이션 타이밍이 발생하여 문제가 해결되는 성가신 버그가있었습니다. 그래도 여전히 OS에 버그가 있다고 생각합니다
SparkyRobinson

.layoutIfNeeded ()를 호출해야한다는 이상한 점이 있지만 Swift 5에서 두 가지 방법으로 테스트했지만 분명히 그것없이 애니메이션됩니다.
wildcat12

2
실제로는 아닙니다. 전화 layoutIfNeeded()를 하지 않으면 버튼을 다시 그려야한다고 플래그가 지정되지만 다음 레이아웃 패스까지는 발생하지 않습니다.performWithoutAnimation
Paulw11

60

참고 :

_button의 " buttonType "이 "UIButtonTypeSystem"인 경우 아래 코드는 유효하지 않습니다 .

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

_button의 " buttonType "이 "UIButtonTypeCustom"인 경우 위 코드가 유효합니다 .


내가 알아 내기 전에 얼마나 많은 시간을 보냈는지 믿을 수 없어요 버튼 유형을 변경하면됩니다.
샌디 채프먼을

코드없이 작동합니다. 버튼 유형 만 변경하면 작동합니다.
Alex Motor

52

iOS 7.1부터 나를 위해 일한 유일한 해결책은 type 버튼을 초기화하는 것 UIButtonTypeCustom입니다.


이것은 UIButtonTypeSystem이 필요없는 사람에게는 가장 현명한 방법입니다.
DonnaLea

이것은 저에게 가장 효과적이었습니다. 방금 CUSTOM 버튼을 만들어 시스템 버튼처럼 보이고 강조 표시했습니다. 차이를 거의 볼 수 없지만 지연이 없습니다.
Travis M.

18

그래서 나는 일한 해결책을 찾습니다.

_logoutButton.titleLabel.text = NSLocalizedString(@"Logout",);
[_logoutButton setTitle:_logoutButton.titleLabel.text forState:UIControlStateNormal];

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


1
나는 같은 해결 방법을 사용합니다. 수락 된 답변이 효과가 없습니다.
deej

이것은 적어도 iOS 8에서 타이틀이 두 번 깜박이게합니다.
Jordan H

1
이것은 7.1과 8.1 모두 깜박이지 않고 작동합니다. 간단하고 효과적입니다.
Todd

두 번째 줄에 동일한 문자열을 다시 사용해야했지만 iOS 11에서 완벽하게 작동합니다 (버튼 레이블의 제목을 사용하면 깜박임).
SilverWolf-복원 모니카

13

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


이 간단한 답변이이 문제를 99 %의 시간으로 해결해야 할 때 이러한 해결 방법 "솔루션"이 어떻게 많은 공감대를 가질 수 있습니까?
Rob

12

스위프트 5

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

왜 이것이 효과가 있는지 잘 모르겠지만 가장 깨끗한 솔루션입니다. UIKit이 이상합니다.
Nathan Hosselton

11

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


지금은 사용하지 않지만 주변에 있으면 매우 편리합니다!
프랜시스 레이놀즈

9

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


1
더 많은 투표를해야합니다! 이러한 다른 해결 방법 대신 근본 원인에서 애니메이션이 완벽하게 작동하고 비활성화됩니다.
Jesper Schläger

7

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

UIView.setAnimationsEnabled(false)제목을 변경 하기 전에 설정 한 다음 다시 true로 설정 하면 전화 한 경우에도 깜박 거리지 않습니다.self.layoutIfNeeded() 않습니다.

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

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

2) setTitle:forState:다음과 같이 재정의하십시오 .

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

    UIView.performWithoutAnimation({

        super.setTitle(title, forState: state)

        self.layoutIfNeeded()
    })
}

Interface Builder에서 버튼 유형을 시스템으로 그대로두고이 접근 방식이 작동하기 위해 사용자 정의 유형으로 변경할 필요가 없습니다.

나는 이것이 다른 누군가를 돕기를 바랍니다. 나는 다른 사람들에게 그것을 피하기 위해 성가신 깜박이는 버튼으로 오랫동안 고투 해 왔습니다.)


잊지 마세요 layoutIfNeeded():]
Tai Le

6

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

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

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

행운을 빕니다!


3

제목 라벨의 레이어에서 애니메이션을 제거 할 수 있습니다.

    [[[theButton titleLabel] layer] removeAllAnimations];

나는 모든 대답을 겪었습니다. 이것은 최고입니다.
Rudolf Adamkovič

2
여전히 깜박이지만 더 좋습니다.
Lucien

이것은 답변이되어야합니다.
mxcl

3

Xhacker Liu의 신속한 4 버전 답변

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

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
} 

1

system유형이있는 UIButton 은에 암시 적 애니메이션이 있습니다 setTitle(_:for:). 두 가지 방법으로 해결할 수 있습니다.

  1. custom코드 또는 인터페이스 빌더에서 버튼 유형을로 설정하십시오 .
let button = UIButton(type: .custom)

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

  1. 코드에서 애니메이션을 비활성화합니다 :
UIView.performWithoutAnimation {
    button.setTitle(title, for: .normal)
    button.layoutIfNeeded()
}

0

이 해결 방법은 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)


이 해결 방법이 더 이상 iOS 7.1에서 작동하지 않음을 확인했습니다.
sCha

7.1 솔루션을 찾았다 고 가정하지 않습니까?
George Green

@GeorgeGreen은 UIButtonTypeSystem에 대한 작동 솔루션을 찾을 수 없습니다 . UIButtonTypeCustom 을 사용해야했습니다 .
sCha

7.1 이후로 모든 주에 제목 변경 사항을 적용해야하며 일반 상태에 대해서만 설정이 적용되지 않습니다. [_button setTitle:@"title" forState:UIControlStateDisabled]
Sam

0

위의 훌륭한 답변을 결합하면 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];
}

0

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

}

이상적이지는 않지만 작동합니다 ..


0

실제로 애니메이션 블록 외부에서 제목을 설정할 수 있습니다 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()
}

0

Xhacker Liu 확장 기능이 Swift 3로 변환되었습니다.

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

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

-1

버튼의 텍스트 애니메이션 및 변경으로 나타나는 문제를 피하기 위해 애니메이션 2 개와 버튼 2 개를 생성하는 것이 더 나은 솔루션 일 수 있습니다.

두 번째 uibutton을 만들고 2 개의 애니메이션을 생성했는데이 솔루션은 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;}];

-1

나는 대답의 조합으로 작동하도록했습니다.

[[[button titleLabel] layer] removeAllAnimations];

    [UIView performWithoutAnimation:^{

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

    }];

-1

기본 구현에서 훌륭하게 재생되는 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)
    }
  }
}

@Fogmeister 1. 답변이 다릅니다. 2. 최신 Swift 구문 3.에 대한 Apple의 API와 일치합니다 UIButton.
Richard Topchii
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.