代码之家  ›  专栏  ›  技术社区  ›  cagreen

iPhone-通过编程将导航栏按钮更改为活动指示器

  •  2
  • cagreen  · 技术社区  · 15 年前

    我在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];
    

    到目前为止,一切都很好。问题是,当下载完成并尝试重新添加刷新按钮时(使用以下方法):

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

    我得到以下错误:
    [uibarbuttonitem retain]:消息发送到释放的实例

    我并没有明确要求释放。

    a)何时/何地解除交易

    b)有没有更好的方法来实现我想要的?

    2 回复  |  直到 8 年前
        1
  •  1
  •   Martin Gordon    15 年前

    将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 retain];

        2
  •  0
  •   LucioB    8 年前

    由于iOS 5引入了ARC,您不再需要做保留。

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

    在接口中声明:

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

    在ViewDidLoad方法中初始化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;
    }