iPhone - 以编程方式将导航栏按钮更改为活动指示器
我已将刷新 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保留]:发送到已释放实例的消息
我没有显式调用释放。
A)何时/何地释放此资源
B)是否有更好的方法来实现我正在寻找的目标?
I have added a refresh UIBarButtonItem to my navigation bar on my iPhone app. When the user taps the button I'd like the refresh button to change to the animated activity indicator and once the operation (in this case a download) is complete switch the activity indicator back to the refresh button.
I have added the refresh button using IB. Then on the button tap I create a new activity indicator and keep an pointer to the original refresh button. Like so:
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];
So far, so good. Problem is that when my download finishes and I try to re-add the refresh button (using the following):
[activityIndicator stopAnimating];
self.navigationItem.leftBarButtonItem = refreshButtonItem;
I get the following error:
[UIBarButtonItem retain]: message sent to deallocated instance
I'm not explicitly calling release.
A) When/where is this being deallocated
B) Is there a better way to achieve what I'm looking for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您将activityButtonItem 分配给leftBarButtonItem 时,leftBarButtonItem 用来指向的项目将被释放。 leftBarButtonItem(以及具有保留选项的所有属性)的实现与此类似:
如果您想在重新分配 leftBarButtonItem 后使用刷新按钮,请将第一行更改为:
refreshButtonItem = [self.navigationItem.leftBarButtonItemretain];< /代码>
When you assign the activityButtonItem to leftBarButtonItem, the item that leftBarButtonItem used to point to is released. The leftBarButtonItem (and all properties with the retain option) are implemented similarly to this:
If you want to use the refreshButtonItem after reassigning the leftBarButtonItem, change your first line to:
refreshButtonItem = [self.navigationItem.leftBarButtonItem retain];
自 iOS 5 引入 ARC 以来,您不再需要保留。
可以按照 @cagreen 的解释获得解决方案,同时可以将refreshButtonItem以及loadingButton和loadingView存储为类属性。
在您的界面中声明:
在 viewDidLoad 方法中初始化loadingButton和loadingView:
然后要显示加载微调器,您可以简单地执行以下操作:
并隐藏:
Since iOS 5 with the introduction of ARC you no longer need to do retain.
Solution can be obtained as @cagreen explained while refreshButtonItem can be stored as class property, as well as loadingButton and loadingView.
In your interface declare:
Init loadingButton and loadingView in your viewDidLoad method:
Then to show the loading spinner you can simply do:
And to hide: