如何更改图片并禁用UIBarButtonItem?

9

我是一个NavigationBar应用程序,有两个视图:一个父视图和一个子视图。在子视图中,我正在添加一个按钮到右上角,如下所示:

- (void)viewDidLoad {
    UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"lock-unlocked.png"] style:UIBarButtonItemStylePlain target:self action:@selector(lockScreen)];
    self.navigationItem.rightBarButtonItem = tempButton;
    [tempButton release];
}

当单击该按钮时,我想要更改rightBarButtonItem的图像并禁用leftBarButtonItem(由控制器自动添加)。基本上有两个按钮状态,锁定和解锁。
问题1: 我能找到的唯一更改图像的方法是创建一个带有新图像的新UIButtonItem,并用该新项替换rightBarButtonItem。但我想知道是否有一种方法可以在不创建新UIBarButtonItem的情况下仅更改图像。如果我不断创建新UIBarButtonItem,是否会导致内存泄漏?
问题2: 如何获取self.navigationItem.leftBarButtonItem并禁用/启用它?我没有手动创建它,它是由控制器自动创建的。我没有看到任何可以启用/禁用其用户交互的UIBarButtonItem方法/属性。
7个回答

18

问题1:在接口中声明UIBarButtonItem *tempButton

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
    UIBarButtonItem *tempButton;
}

@property (nonatomic, retain) UIBarButtonItem *tempButton;

并在实现中进行合成。

@synthesize tempButton;

在viewDidLoad中创建对象,方法与您现在使用的方式类似。

- (void)viewDidLoad {
  tempButtom = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"lock-unlocked.png"] style:UIBarButtonItemStylePlain target:self action:@selector(lockScreen)];
  self.navigationItem.rightBarButtonItem = tempButton;
}

不要在这里释放它,通常会在底部找到dealloc方法时释放它。

然后当调用lockScreen时执行以下操作

tempButton.image = [UIImage imageNamed:@"myImage.png"]

抱歉,我没有问题2的答案!


1
那种方法看起来好多了。谢谢! - subjective-c
3
第三段代码有一个小问题:你可以在分配内存后释放tempButton,因为当你将其声明为属性时,它已经被保留(retain)了。 - Chilly Zhong
实际上是iPhoney。因为他没有调用self.tempButton,所以该属性不会被保留。只有使用self.VAR才能触发保留属性。 - tony.tc.leung

7
关于问题2,请使用“enabled”属性:
 self.navigationItem.leftBarButtonItem.enabled = NO;

5

如果你有一个navigationController,那么要禁用返回按钮,你需要调用以下方法:

self.navigationItem.hidesBackButton = YES;

这不会隐藏按钮而不是禁用它吗? - Scott McKenzie

1
上面的代码中是否应该在[self.window addSubView:l]调用后release UILabel *l呢?这样它被添加到Subview中时会+1保留,但在同一分支中会释放-1。否则,您必须调用disableLeftBarButtonItemOnNavbar:NO来释放它。虽然最终结果相同,但如果此代码位于单独的分支中,我认为内置在XCode中的静态分析工具可能不会喜欢这样。只是一个小细节 :-)
- (void) disableLeftBarButtonItemOnNavbar:(BOOL)disable
{
    static UILabel *l = nil;

    if (disable) {
        if (l != nil)
            return;
        l = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 160, 44)];
        l.backgroundColor = [UIColor clearColor];
        l.userInteractionEnabled = YES;
        [self.window addSubview:l];
        [l release];
    }
    else {
        if (l == nil)
            return;
        [l removeFromSuperview];
        l = nil;
    }
}

0

我无法使用以下代码禁用/灰化NavBar按钮:

self.navigationItem.leftBarButtonItem.enabled = NO;

......但隐藏返回按钮效果不错!

self.navigationItem.hidesBackButton = YES;

谢谢Dzamir!


0

使用“hidesBackButton=YES”并不是一个优雅的解决方案,因为它会隐藏按钮,这不是我们想要的。一个可接受的解决方法是在窗口中添加一个UILabel,将其放置在返回按钮上方,至少禁用按钮的触摸。

将此方法添加到您的AppDelegate类中:

- (void) disableLeftBarButtonItemOnNavbar:(BOOL)disable
{
    static UILabel *l = nil;

    if (disable) {
        if (l != nil)
            return;
        l = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 160, 44)];
        l.backgroundColor = [UIColor clearColor];
        l.userInteractionEnabled = YES;
        [self.window addSubview:l];
    }
    else {
        if (l == nil)
            return;
        [l removeFromSuperview];
        [l release];
        l = nil;
    }
}

您可以从任何视图控制器中调用以下代码来禁用它:

MyAppDelegate *appDeleg = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDeleg disableLeftBarButtonItemOnNavbar:YES];

启用:

MyAppDelegate *appDeleg = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDeleg disableLeftBarButtonItemOnNavbar:NO];

0

我认为这段代码可以帮助你,

UIButton *m_objbtnFlip= [[UIButton alloc] initWithFrame:CGRectMake(0,0,89, 37)];
    [m_objbtnFlip setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"btn_purchased"
                                                                                                 ofType:IMAGETYPE]]
                       forState:UIControlStateNormal];
    [m_objbtnFlip setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"btn_allavailable"
                                                                                                 ofType:IMAGETYPE]]
                       forState:UIControlStateSelected];
    [m_objbtnFlip addTarget:self action:@selector(flipViews) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *objBarButtonItemRight = [[UIBarButtonItem alloc] initWithCustomView:m_objbtnFlip];

    self.navigationItem.rightBarButtonItem=objBarButtonItemRight;
    [objBarButtonItemRight release];
    objBarButtonItemRight = nil;

在这里编写操作代码:

-(void)flipViews    {
   // put action code here
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接