iphone-以编程方式将导航栏按钮更改为活动指示器

iphone-以编程方式将导航栏按钮更改为活动指示器,iphone,uinavigationbar,uiactivityindicatorview,Iphone,Uinavigationbar,Uiactivityindicatorview,我在iPhone应用程序的导航栏中添加了一个刷新UIBarButtonItem。当用户点击按钮时,我希望刷新按钮更改为动画活动指示器,并且一旦操作(在本例中为下载)完成,将活动指示器切换回刷新按钮 我使用IB添加了刷新按钮。然后点击按钮,我创建了一个新的活动指示器,并保留一个指向原始刷新按钮的指针。像这样: refreshButtonItem = self.navigationItem.leftBarButtonItem; if (activityButtonItem == nil) {

我在iPhone应用程序的导航栏中添加了一个刷新UIBarButtonItem。当用户点击按钮时,我希望刷新按钮更改为动画活动指示器,并且一旦操作(在本例中为下载)完成,将活动指示器切换回刷新按钮

我使用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];
到目前为止,一切顺利。问题是,当我的下载完成后,我尝试重新添加刷新按钮(使用以下命令):

我得到以下错误:
[UIBarButtonItem retain]:发送到解除分配实例的消息

我没有明确要求释放

A) 何时/何地解除分配


B) 有没有更好的方法来实现我想要的功能?

当您将activityButtonItem分配给leftBarButtonItem时,leftBarButtonItem用来指向的项目将被释放。leftBarButtonItem(以及所有带有retain选项的属性)的实现方式与此类似:

- (void)leftBarButtonItem:(UIBarButtonItem *)newItem {
  if (newItem != self.leftBarButtonItem) {
    [self.leftBarButtonItem release];
    leftBarButtonItem = [newItem retain];
  }
}
如果要在重新指定leftBarButtonItem后使用refreshButtonItem,请将第一行更改为:


refreshButtonItem=[self.navigationItem.leftBarButtonItem]保留

自从iOS 5引入ARC后,您不再需要再做保留

可以按照@cagreen的解释获得解决方案,而refreshButtonItem可以存储为类属性,以及loadingButton和loadingView

在界面中声明:

@property (strong, nonatomic) UIBarButtonItem *refreshButton;
@property (strong, nonatomic) UIBarButtonItem *loadingButton;
@property (strong, nonatomic) UIActivityIndicatorView *loadingView;
viewDidLoad方法中的Init loadingButton和loadingView:

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;
}
 // Hides loading button
- (void)hideLoadingView {
    [self.loadingView stopAnimating];
    self.navigationItem.rightBarButtonItem = self.refreshButton;
}