Как изменить изображение и отключить UIBarButtonItem - PullRequest
8 голосов
/ 11 февраля 2009

У меня есть приложение 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 голосов
/ 11 февраля 2009

Вопрос 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, я боюсь!

7 голосов
/ 23 мая 2009

В отношении вопроса 2 используйте свойство enabled:

 self.navigationItem.leftBarButtonItem.enabled = NO;
5 голосов
/ 24 августа 2009

Я не могу понять, есть ли у вас навигационный контроллер, но в этом случае, чтобы отключить кнопку возврата, нужно позвонить:

self.navigationItem.hidesBackButton = YES;
1 голос
/ 17 сентября 2010

Разве вышеперечисленное не должно освобождать UILabel * l после вызова [self.window addSubView: l]? Таким образом, он получает +1 при добавлении в Subview, но освобождает -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 голосов
/ 11 ноября 2010

Я думаю, этот код поможет вам,

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
}
0 голосов
/ 31 июля 2010

Использование «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 голосов
/ 13 ноября 2009

Мне не удалось отключить / заштриховать кнопку NavBar с помощью:

self.navigationItem.leftBarButtonItem.enabled = NO;

... но скрытие кнопки "назад" работает хорошо!

self.navigationItem.hidesBackButton = YES;

Спасибо, Дзамир!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...