Как переопределить действие self.navigationItem.backBarButtonItem?

Я хочу переопределить self.navigationItem.backBarButtonItemцель и действие,

Я старался:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(backButtonOverrideAction:)];
[self.navigationItem setLeftBarButtonItem:backButton];

это работает, но я хочу использовать стрелку по умолчанию:

я также попробовал:

UIBarButtonItem *backButton = self.navigationItem.backBarButtonItem;
[backButton setTarget:self];
[backButton setAction:@selector(backButtonOverrideAction:)];

но, к сожалению, это не работает.. у вас есть идеи, как это сделать?

8 ответов

Решение

И все же, нет прямого доступа для изменения цели и действия на self.navigationItem.backBarButtonItem,

Я закончил тем, что использовал первый, который попробовал... и получил свое (пользовательское) изображение..

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"myImage.png"]
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(backButtonOverrideAction:)];
[self.navigationItem setLeftBarButtonItem:backButton];

в то время как...

//this two lines of code are still useless, i just feel sorry for them.. 
[self.navigationItem.backBarButtonItem setTarget:<#(id)#>];
[self.navigationItem.backBarButtonItem setAction:<#(SEL)#>];

Вы не можете назначить действие обратно BarButton. Решением для этого является создание пользовательской кнопки возврата.

В Swift 3.1

override func viewDidLoad() {    
// set navigationItem.leftBarButtonItem return to Root
let backToRootVCButton = UIBarButtonItem.init(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(backToRootVCAction))
self.navigationItem.setLeftBarButton(backToRootVCButton, animated: true)

}

func backToRootVCAction() {
    _ = self.navigationController?.popToRootViewController(animated: true)
}

«backAction» (новое в iOS16)

Если кнопка «Назад» уже отображается на панели навигации, установка этого свойства заменяет ее действие без изменения ее внешнего вида. В противном случае установка этого свойства создает кнопку «Назад» с изображением или заголовком из указанного вами действия, если вы не используете стиль навигации UINavigationItemStyleEditor.

https://developer.apple.com/documentation/uikit/uinavigationitem/3987966-backaction?language=objc

Это работает для 11.3:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let BackItemIndex = 2
    if let subViews = navigationController?.navigationBar.subviews, 
        subViews.count > BackItemIndex {
            navigationController?.navigationBar.subviews[BackItemIndex].subviews.first?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(doPerformAction(_:))))
    }
}

@objc func doPerformAction(_ sender: Any) {
    // some code
}

Это решение основано на поиске активных подпредставлений до тех пор, пока они не соответствуют backBarButtonItem, а затем добавлении UITapGestureRecognizer, чтобы он захватывал событие в элементе.

Отрывок из Apple Doc гласит:

При указании кнопок для элемента навигации вы должны использовать объекты UIBarButtonItem. Если вы хотите отобразить пользовательские представления на панели навигации, вы должны обернуть эти представления внутри объекта UIBarButtonItem перед добавлением их в элемент навигации.

Это означает, что вы просто не можете использовать метод 2 из вашего вопроса. Принимая во внимание, что метод-1 - верный способ сделать это.

Я надеюсь, что это поможет вам...

BOOL IsOK_Clicked;

-(void)viewDidAppear:(BOOL)animated
{
 IsOK_Clicked = NO;
}
-(void)viewDidDisappear:(BOOL)animated
{
   if(!IsOK_Clicked){
    //Do what you want in Back Click
  }
}
- (IBAction)btnCheckOut:(id)sender {
 IsOK_Clicked = YES;
}

Или Вы можете добавить элемент левой кнопки на панель навигации и установить для него собственную функцию выбора.

Вы должны сделать что-то вроде

self.navigationItem.backBarButtonItem.target = self;
self.navigationItem.backBarButtonItem.action = @selector(backButtonAction:);

здесь вы должны обработать поп для контроллера также.

Другие вопросы по тегам