Override back button in navigation stack while keeping appearance of default back button?

时光总嘲笑我的痴心妄想 提交于 2019-11-27 01:38:03

问题


How do I override the back button for just one view (not for all the back buttons present in different views) such that on click of the back button, root view controller is shown.


回答1:


You need to replace the backbutton and associate an action handler:

- (void)viewDidLoad {
    [super viewDidLoad];

    // change the back button to cancel and add an event handler
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@”back”
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(handleBack:)];

    self.navigationItem.leftBarButtonItem = backButton;
}

- (void)handleBack:(id)sender {
    // pop to root view controller
    [self.navigationController popToRootViewControllerAnimated:YES];
}



回答2:


Found a solution which retains the back button style as well. Add the following method to your view controller.

-(void) overrideBack{

    UIButton *transparentButton = [[UIButton alloc] init];
    [transparentButton setFrame:CGRectMake(0,0, 50, 40)];
    [transparentButton setBackgroundColor:[UIColor clearColor]];
    [transparentButton addTarget:self action:@selector(backAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.navigationController.navigationBar addSubview:transparentButton];


}

Now provide a functionality as needed in the following method:

-(void)backAction:(UIBarButtonItem *)sender {
    //Your functionality
}

All it does is to cover the back button with a transparent button ;)




回答3:


It's old, but the correct answer is that:

Instead of pushing your ViewController on top of all the others, you'd better replace the full stack with the rootVC and the new VC only.

Not:

self.navigationController?.pushViewController(myVc, animated: true)

But:

let vcStack = self.navigationController?.viewControllers
self.navigationController?.setViewControllers([vcStack![0],myVc], animated: true)

Like that, on back it will just popToRoot because it's the previous viewController in stack




回答4:


I had the similar problem and I successfully used the answer given by Sarasranglt. Here is the SWIFT version.

    override func viewDidLoad() {
       let transparentButton = UIButton()
       transparentButton.frame = CGRectMake(0, 0, 50, 40)
       transparentButton.backgroundColor = UIColor.orangeColor()
       transparentButton.addTarget(self, action:"backAction:", forControlEvents:.TouchUpInside)
       self.navigationController?.navigationBar.addSubview(transparentButton)
    }

And the function is

 func backAction(sender:UIButton) {
     // Some sction
 }



回答5:


Another approach is to adopt UINavigationControllerDelegate Protocol.

– navigationController:willShowViewController:animated:
– navigationController:didShowViewController:animated:

Those methods will let you know when a controller appears but you have to check that controller is the controller you want.




回答6:


For keeping same appearance you can use :

UIView *leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(-12, 0, 105, 30)];

UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
leftButton.frame = leftButtonView.frame;
[leftButton setImage:[UIImage imageNamed:@"ic_system_back"] forState:UIControlStateNormal];
[leftButton setTitle:@"title" forState:UIControlStateNormal];
[leftButton.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
[leftButton.titleLabel setFont:[UIFont systemFontOfSize:16]];
[leftButton setTitleEdgeInsets: UIEdgeInsetsMake(0, 8, 0, 0)];
[leftButton addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
[leftButtonView addSubview:leftButton];

UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:leftButtonView];
self.navigationItem.leftBarButtonItem = leftBarButton;



回答7:


Following Sarasranglt's method of having a transparent button, in objective C, and Pavle Mijatovic's earlier swift version, here is a swift 4 version:

let transparentButton = UIButton()
transparentButton.frame = CGRect(x:0, y:0, width:50, height: 40)
transparentButton.backgroundColor = UIColor.clear
transparentButton.addTarget(self, action:#selector(backAction(sender:)), for:.touchUpInside)
self.navigationController?.navigationBar.addSubview(transparentButton)

and

@objc func backAction(sender:UIButton) {
// Some action
}



回答8:


Use this code to show a custom back button, Note the backBarButtonItem before marking it as a duplicate answer.

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"< back"
                                                               style:UIBarButtonItemStylePlain
                                                              target:self
                                                              action:@selector(handleBack:)];

self.navigationItem.backBarButtonItem= backButton;

Cheers!



来源:https://stackoverflow.com/questions/5085452/override-back-button-in-navigation-stack-while-keeping-appearance-of-default-bac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!