如何更改图像并禁用UIBarButtonItem

时间:2009-02-11 11:33:51

标签: iphone cocoa-touch

我有一个带有两个视图的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 个答案:

答案 0 :(得分: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 :(得分:7)

关于问题2,请使用'enabled'属性:

 self.navigationItem.leftBarButtonItem.enabled = NO;

答案 2 :(得分:5)

我无法理解你是否有一个navigationController,但在这种情况下要禁用你需要调用的后退按钮:

self.navigationItem.hidesBackButton = YES;

答案 3 :(得分:1)

在[self.window addSubView:l]调用之后,上面是否应该释放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;
    }
}

答案 4 :(得分:0)

我无法使用以下内容禁用/灰显NavBar按钮:

self.navigationItem.leftBarButtonItem.enabled = NO;

...但隐藏后退按钮效果很好!

self.navigationItem.hidesBackButton = YES;

谢谢Dzamir!

答案 5 :(得分: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];

答案 6 :(得分: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
}