Override back button in navigation stack while keeping appearance of default back button?
How do I override the 开发者_JS百科back button for just one view (not for all the back buttons present in different views) such that on click of the back button, the root view controller is shown?
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];
}
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 ;)
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
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
}
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.
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;
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
}
without making custom button or without any hack(transparentButton) just override 'viewWillDisappear' method and write your code inside the block.
override func viewWillDisappear(_ animated: Bool) {
// write your code...
}
The following code (written in C# for Xamarin iOS) will replace the back button with a custom one that looks just like the system implementation (chevron icon included).
The system "back" navigation will no longer fire, and you are free to handle the TouchUpInside as you wish.
Converting it to ObjC shouldn't take long, I'll leave that fun to you :)
var backButton = new UIButton(new CGRect(0, 0, 70.0, 70.0));
var symbolCfg = UIImageSymbolConfiguration.Create(UIFont.ButtonFontSize, UIImageSymbolWeight.Bold, UIImageSymbolScale.Large)
var backImage = UIImage.GetSystemImage("chevron.left", symbolCfg);
backButton.SetImage(backImage, forState: UIControlState.Normal);
backButton.TitleEdgeInsets = new UIEdgeInsets(10.0f, 10.0f, 10.0f, 0.0f);
backButton.SetTitle("Back", forState: UIControlState.Normal);
var backBarButton = new UIBarButtonItem(customView: backButton);
NavigationItem.LeftBarButtonItems = new[] { backBarButton };
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!
精彩评论