Как предотвратить мигание UIButton при обновлении заголовка


когда я вызываю setTitle на UIButton, кнопка мигает в iOS 7. Я попытался установить myButton.выделено = нет, но это не помешало кнопке мигать.

[myButton setTitle:[[NSUserDefaults standardUserDefaults] stringForKey:@"elapsedLabelKey"] forState:UIControlStateNormal];

myButton.highlighted = NO;

вот как я настроил таймер, который обновил названия:

- (void)actionTimer {
    if (myTimer == nil) {

        myTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0
                        target: self
                        selector: @selector(showActivity)
                        userInfo: nil
                        repeats: YES];
    }
}

вот метод, который на самом деле обновляет названия:

- (void)showActivity {

    NSString *sym = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];

    if (pauseInterval == nil) {

        // Update clock
        seconds = [[NSDate date] timeIntervalSinceDate:startInterval] - breakTime;

        // Update total earned
        secRate = rate.value / 60 / 60;
        total = secRate * seconds;
        [totalLabel setTitle:[NSString stringWithFormat:@"%@%.4f",sym,total] forState:UIControlStateNormal];

        days = seconds / (60 * 60 * 24);
        seconds -= days * (60 * 60 * 24);
        int hours = seconds / (60 * 60);
        fhours = (float)seconds / (60.0 * 60.0);
        seconds -= hours * (60 * 60);
        int minutes = seconds / 60;
        seconds -= minutes * 60;

        // Update the timer clock
        [elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
    }
}
9 61

9 ответов:

мигание не вызвано таймером как таковым. Метод UIButton setTitle:forState вызывает мигание. Одна простая работа заключается в использовании UIButton без названия и наложении UILabel. При изменении текста UILabel он не будет мигать.

выберите тип кнопки UIButtonTypeCustom и он перестанет мигать

*Пожалуйста, обратите внимание *

, когда "buttonType" из-_button составляет "UIButtonTypeSystem", код недействительным

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

, когда "buttonType" из-_button составляет "UIButtonTypeCustom" выше код действительный.

лучше, чем [UIView setAnimationsEnabled:NO] который может повлиять на другие анимации, чтобы отключить только определенную анимацию заголовка.

Цель-C:

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

Swift 3:

UIView.performWithoutAnimation { 
    myButton.setTitle(text, for: .normal)
    myButton.layoutIfNeeded()
}

посмотреть ответы Как остановить нежелательную анимацию UIButton при изменении названия?:

[UIView setAnimationsEnabled:NO];
[elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

по умолчанию "setTitle" поведение определенно ненавистно!

мое решение:

[UIView setAnimationsEnabled:NO];
[_button layoutIfNeeded]; 
[_button setTitle:[NSString stringWithFormat:@"what" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

кроме того, в раскадровке, под свойством кнопки я снимаю флажок:

  • Реверс На Подсветку
  • Выделено Настроить Изображение

и регистрации:

  • Отключена Настройка Изображения

протестировано и работает над iOS 8 тоже.

обновление - Свифт

Я предлагаю вам создать свою пользовательскую кнопку и переопределить setTitle метод.

class UnflashingButton: UIButton {

    override func setTitle(title: String?, forState state: UIControlState) {
        UIView.setAnimationsEnabled(false)
        self.layoutIfNeeded()
        super.setTitle(title, forState: state)
        UIView.setAnimationsEnabled(true)
    }

}

вы можете просто просто сделать другую функцию для UIButton для легкого использования в будущем.

extension UIButton {
    func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
        UIView.performWithoutAnimation {
            self.setTitle(title, for: controlState)
            self.layoutIfNeeded()
        }
    }
}

вот оно!

и просто установите название, как вы бы раньше, но заменить setTitle С setTitleWithoutAnimation

Я новичок в кодировании и Stackoverflow, поэтому у меня недостаточно репутации, чтобы комментировать напрямую, чтобы расширить https://stackoverflow.com/users/4673064/daniel-tseng Отличный ответ. Поэтому я должен написать свой собственный новый ответ, и это так:

extension UIButton {
    func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
        UIView.performWithoutAnimation {
            self.setTitle(title, for: controlState)
            self.layoutIfNeeded()
        }
    }
}

отлично работает, за исключением:

Если все мои вызовы позже в коде "setTitleWithoutAnimation" не указывают отправителя, то я получаю эти странные сообщения, связанные с CoreMedia или CoreData, например, " не удалось наследовать разрешения CoreMedia от 2526: (null)"

Это, вероятно, довольно простой для кодирования и iOS, но для меня, как новый кодер, он отправил меня на кроличий след на некоторое время, как в: сегодня расширение не удалось унаследовать разрешения CoreMedia от, где у людей были интересные ответы, но это не добраться до корня моей проблемы.

таким образом, я, наконец, обнаружил, что мне нужно было пройти и дать мои параметры функций без параметров, т. е. мне нужно было указать отправителя. Отправитель может быть UIButton, любой, или какой-либо объект. Все это сработало, но в конечном итоге возникает конфликт между добавлением расширения кнопки с помощью "self" и не говоря конкретно о том, что кнопка использует его.

опять же, вероятно, основной, но новый для меня, поэтому я решил, что стоит поделиться.

попробуйте это, это работает в более новых версиях IOS:

class CustomButtonWithNoEffect : UIButton {
    override func setTitle(_ title: String?, for state: UIControlState) {
        UIView.performWithoutAnimation {
            super.setTitle(title, for: state)
            super.layoutIfNeeded()
        }
    }

}