【问题标题】:How to change image and disable UIBarButtonItem如何更改图像和禁用 UIBarButtonItem
【发布时间】:2009-02-11 11:33:50
【问题描述】:

我有一个带有两个视图的 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 上没有看到任何方法/属性来启用/禁用用户与之交互。

【问题讨论】:

    标签: iphone cocoa-touch


    【解决方案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 的答案!

    【讨论】:

    • 这种方法看起来好多了。谢谢!
    • 第三段代码的一个小问题:你可以在 alloc 之后释放 tempButton,因为当你将它声明为属性时它已经被保留了。
    • 实际上是 iPhoney。因为他没有调用self.tempButton,所以属性不会保留。仅当您使用 self.VAR 时才能触发保留属性
    【解决方案2】:

    关于问题 2,使用“启用”属性:

     self.navigationItem.leftBarButtonItem.enabled = NO;
    

    【讨论】:

      【解决方案3】:

      我不明白你是否有一个导航控制器,但在这种情况下,你需要调用禁用后退按钮:

      self.navigationItem.hidesBackButton = YES;
      

      【讨论】:

      • 这不是隐藏而不是禁用按钮吗?
      【解决方案4】:

      不应该在 [self.window addSubView:l] 调用之后释放 UILabel *l 吗?这样它在添加到子视图时会保留 +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;
          }
      }
      

      【讨论】:

        【解决方案5】:

        我无法通过以下方式禁用/灰显导航栏按钮:

        self.navigationItem.leftBarButtonItem.enabled = NO;
        

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

        self.navigationItem.hidesBackButton = YES;
        

        谢谢扎米尔!

        【讨论】:

          【解决方案6】:

          使用“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];
          

          【讨论】:

            【解决方案7】:

            我认为这段代码对你有帮助,

            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
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多