覆盖导航堆栈中的后退按钮,同时保持默认后退按钮的外观?

发布于 2024-10-19 06:21:31 字数 59 浏览 1 评论 0原文

如何仅覆盖一个视图的后退按钮(而不是不同视图中存在的所有后退按钮),以便单击后退按钮时显示根视图控制器?

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, the root view controller is shown?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

睡美人的小仙女 2024-10-26 06:21:31

您需要替换后退按钮并关联一个操作处理程序:

- (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];
}

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];
}
如若梦似彩虹 2024-10-26 06:21:31

找到了一个也保留后退按钮样式的解决方案。
将以下方法添加到您的视图控制器中。

-(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
}

它所做的只是用透明按钮覆盖后退按钮;)

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 ;)

终陌 2024-10-26 06:21:31

它很旧,但正确的答案是:

不要将 ViewController 推到所有其他视图控制器之上,而是最好仅使用 rootVC 和新 VC 替换整个堆栈。

不是:

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

但是:

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

像这样,在后面它只会 popToRoot 因为它是堆栈中的前一个 viewController

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

记忆之渊 2024-10-26 06:21:31

我遇到了类似的问题,我成功地使用了 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
 }

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
 }
只想待在家 2024-10-26 06:21:31

另一种方法是采用 UINavigationControllerDelegate协议。

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

这些方法会让您知道控制器何时出现,但您必须检查该控制器是您想要的控制器。

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.

拥醉 2024-10-26 06:21:31

为了保持相同的外观,您可以使用:

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;

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;
明月夜 2024-10-26 06:21:31

遵循 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
}

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
}
唱一曲作罢 2024-10-26 06:21:31

无需制作自定义按钮或无需任何 hack(transparentButton) 只需重写“viewWillDisappear”方法并将代码写入块内。

override func viewWillDisappear(_ animated: Bool) {
        // write your code...
}

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...
}
随梦而飞# 2024-10-26 06:21:31

以下代码(针对 Xamarin iOS 用 C# 编写)将用看起来与系统实现类似的自定义按钮替换后退按钮(包括 V 形图标)。

系统“后退”导航将不再触发,您可以随意处理 TouchUpInside。

屏幕截图实现

将其转换为 ObjC 应该不会花很长时间,我会把这个乐趣留给你:)

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 };

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.

Screenshot of implementation

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 };
给我一枪 2024-10-26 06:21:31

使用此代码显示自定义后退按钮,在将其标记为重复答案之前请注意 backBarButtonItem

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

self.navigationItem.backBarButtonItem= backButton;

干杯!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文