【发布时间】:2011-02-22 23:48:35
【问题描述】:
我如何只为一个视图覆盖后退按钮(不是为不同视图中存在的所有后退按钮),以便在单击后退按钮时显示根视图控制器?
【问题讨论】:
-
你不能完全按照你的意愿去做。您必须执行其他两个答案提供的类似操作。如果您想保留 back 的所有特征,但要覆盖有时会发生的情况,请选择 nacho4d 的答案。否则,更喜欢 Mike Bretz 的回答。
我如何只为一个视图覆盖后退按钮(不是为不同视图中存在的所有后退按钮),以便在单击后退按钮时显示根视图控制器?
【问题讨论】:
您需要替换后退按钮并关联一个动作处理程序:
- (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];
}
【讨论】:
找到了一个同样保留后退按钮样式的解决方案。 将以下方法添加到您的视图控制器。
-(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];
}
现在根据需要在下面的方法中提供一个功能:
-(void)backAction:(UIBarButtonItem *)sender {
//Your functionality
}
它所做的只是用透明按钮覆盖后退按钮;)
【讨论】:
-viewWillLayoutSubviews 中是正确的,否则你的后退按钮可能有一个大标题并且这个按钮赢了不要覆盖它。更好的解决方案是用带有图像和标签的自定义视图完全替换后退按钮以复制样式。还有无数其他更好的解决方案,这个本身就是 hacky。
老了,但正确答案是:
与其把你的 ViewController 压在所有其他的之上,你最好用 rootVC 和新的 VC 替换整个堆栈。
不是:
self.navigationController?.pushViewController(myVc, animated: true)
但是:
let vcStack = self.navigationController?.viewControllers
self.navigationController?.setViewControllers([vcStack![0],myVc], animated: true)
这样,在后面它只会popToRoot,因为它是堆栈中的前一个viewController
【讨论】:
我有类似的问题,我成功地使用了 Sarasranglt 给出的答案。这是 SWIFT 版本。
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)
}
而功能是
func backAction(sender:UIButton) {
// Some sction
}
【讨论】:
另一种方法是采用UINavigationControllerDelegate协议。
– navigationController:willShowViewController:animated:
– navigationController:didShowViewController:animated:
这些方法会在控制器出现时通知您,但您必须检查该控制器是您想要的控制器。
【讨论】:
为了保持相同的外观,您可以使用:
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;
【讨论】:
遵循 Sarasranglt 在 Objective C 中使用透明按钮的方法,以及 Pavle Mijatovic 早期的 swift 版本,这里是一个 swift 4 版本:
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)
和
@objc func backAction(sender:UIButton) {
// Some action
}
【讨论】:
无需制作自定义按钮或没有任何 hack(transparentButton) 只需覆盖 'viewWillDisappear' 方法并在块内编写代码。
override func viewWillDisappear(_ animated: Bool) {
// write your code...
}
【讨论】:
使用此代码显示自定义后退按钮,请注意backBarButtonItem,然后再将其标记为重复答案。
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"< back"
style:UIBarButtonItemStylePlain
target:self
action:@selector(handleBack:)];
self.navigationItem.backBarButtonItem= backButton;
干杯!
【讨论】: