iphone - программно изменить кнопку панели навигации на индикатор активности - PullRequest
2 голосов
/ 12 февраля 2010

Я добавил обновленный UIBarButtonItem в панель навигации в приложении для iPhone. Когда пользователь нажимает кнопку, я бы хотел, чтобы кнопка обновления сменилась на анимированный индикатор активности, и после завершения операции (в данном случае загрузка) переключите индикатор активности обратно на кнопку обновления.

Я добавил кнопку обновления с помощью IB. Затем на кнопке нажмите, чтобы создать новый индикатор активности и сохранить указатель на исходную кнопку обновления. Вот так:

refreshButtonItem = self.navigationItem.leftBarButtonItem;
if (activityButtonItem == nil)
{
    activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20,20)];
    activityButtonItem = [[UIBarButtonItem alloc]initWithCustomView:activityIndicator];

}
self.navigationItem.leftBarButtonItem = activityButtonItem;
[activityIndicator startAnimating];

Пока все хорошо. Проблема в том, что когда моя загрузка заканчивается, и я пытаюсь повторно добавить кнопку обновления (используя следующее):

[activityIndicator stopAnimating];
self.navigationItem.leftBarButtonItem = refreshButtonItem;

Я получаю следующую ошибку:
[UIBarButtonItem retain]: сообщение отправлено на освобожденный экземпляр

Я явно не называю релиз.

A) Когда / где это освобождается

B) Есть ли лучший способ достичь того, что я ищу?

Ответы [ 2 ]

1 голос
/ 12 февраля 2010

Когда вы присваиваете actionButtonItem для leftBarButtonItem, элемент, на который leftBarButtonItem использовался для указания, освобождается. LeftBarButtonItem (и все свойства с опцией сохранения) реализованы аналогично этому:

- (void)leftBarButtonItem:(UIBarButtonItem *)newItem {
  if (newItem != self.leftBarButtonItem) {
    [self.leftBarButtonItem release];
    leftBarButtonItem = [newItem retain];
  }
}

Если вы хотите использовать refreshButtonItem после переназначения leftBarButtonItem, измените первую строку на:

refreshButtonItem = [self.navigationItem.leftBarButtonItem retain];

0 голосов
/ 20 января 2017

Начиная с iOS 5 с введением ARC вам больше не нужно сохранять.

Решение можно получить, как объяснил @cagreen, а refreshButtonItem можно сохранить как свойство класса, а также loadingButton и loadingView.

В вашем интерфейсе объявите:

@property (strong, nonatomic) UIBarButtonItem *refreshButton;
@property (strong, nonatomic) UIBarButtonItem *loadingButton;
@property (strong, nonatomic) UIActivityIndicatorView *loadingView;

Инициализация loadButton и loadingView в вашем методе viewDidLoad:

self.loadingView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
self.loadingButton = [[UIBarButtonItem alloc] initWithCustomView:self.loadingView];

Затем, чтобы показать загрузочный счетчик, вы можете просто сделать:

 // Shows loading button
- (void)showLoadingView {

    // Keep reference to right bar button
    if (self.navigationItem.rightBarButtonItem) {
        self.refreshButton = self.navigationItem.rightBarButtonItem;
    }

    // Start animating and assign loading button to right bar button
    [self.loadingView startAnimating];
    self.navigationItem.rightBarButtonItem = self.loadingButton;
}

И скрыть:

 // Hides loading button
- (void)hideLoadingView {
    [self.loadingView stopAnimating];
    self.navigationItem.rightBarButtonItem = self.refreshButton;
}
...