【问题标题】:Action to Navigation bar back button导航栏后退按钮的操作
【发布时间】:2017-06-25 13:36:42
【问题描述】:

我想在用户单击后退按钮时显示带有确认的警报。这就是我尝试添加操作的方式。

self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "<", style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.save(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton

这工作正常,但我想要其中的默认后退按钮图像而不是自定义标题。该怎么做?

我也尝试了以下代码:

self.navigationItem.backBarButtonItem?.action = #selector(ViewController.save(sender:))

...但是也没有执行该操作。

【问题讨论】:

  • 我认为你可以设置正确的后退箭头图像,这里是assets 下载它并将其添加到自定义后退按钮。
  • self.navigationItem.hidesBackButton = true;如果是真的?这意味着您也无法获得标准的后退按钮及其图标。
  • @Mannopson 是的,我已将其设置为 true。
  • @Nitesh 我有同样的问题,也许是一个错误。我用过 Swift 3.0 和 Xcode 8.0
  • @Nitesh 您是否已经使用UINavigationControllerDelegate 方法尝试过我建议的解决方案?

标签: ios swift


【解决方案1】:

这可能会有所帮助。这不会覆盖返回操作,但您可以执行其他任务。

目标c

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if(self.isMovingFromParentViewController)
    {
        //On click of back or swipe back
    }
    if(self.isBeingDismissed)
    {
        //Dismissed
    }
    NSLog(@"%d",self.isBeingDismissed);
    NSLog(@"%d",self.isMovingFromParentViewController);
}

斯威夫特

override func viewWillDisappear(_ animated: Bool)
{
    super.viewWillDisappear(animated);
    if self.isMovingFromParentViewController
    {
        //On click of back or swipe back
    }
    if self.isBeingDismissed
    {
        //Dismissed
    }
}

【讨论】:

  • 但如果我这样做,则不会显示警报。
  • 警报不会显示在此视图控制器上,因为它即将消失。尝试在将要显示的上一个视图控制器上显示。
【解决方案2】:

我找到了解决办法!

我在 iOS 11 和 iOS 13 上对其进行了测试,它运行良好 :)

protocol CustomNavigationViewControllerDelegate {
    func shouldPop() -> Bool
}

class CustomNavigationViewController: UINavigationController, UINavigationBarDelegate {
    var backDelegate: CustomNavigationViewControllerDelegate?

    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        return backDelegate?.shouldPop() ?? true
    }
}

class SecondViewController: UIViewController, CustomNavigationViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        (self.navigationController as? CustomNavigationViewController)?.backDelegate = self
    }

    func shouldPop() -> Bool {
        if (needToShowAlert) {
            showExitAlert()
            return false

        } else {
            return true
        }
    }
}

【讨论】:

  • 谢谢,这对我很有效。但是,SecondViewController消失的时候不需要清除backDelegate吗?
【解决方案3】:

您需要向导航栏添加自定义后退按钮,并为其添加操作

      let backButton = UIBarButtonItem (image: UIImage(named: "ico-nav-prev")!, style: .plain, target: self, action: #selector(GoToBack))
      self.navigationItem.leftBarButtonItem = backButton
      self.navigationItem.hidesBackButton = true

     func GoToBack(){

        self.navigationController!.popViewController(animated: true)

      }

【讨论】:

    【解决方案4】:

    我不知道你想达到什么目标,但这难道不是一个可行的解决方案,你想要什么,只要vieWillDisappear: 被调用?这可能是一个匹配的入口点,而无需摆弄其他答案中建议的后退栏按钮。

    更好 另一种选择是实现UINavigationControllerDelegate,将您的控制器设置为delegate,然后在navigationController(_:willShow:animated:) 中实现您的警报。

    查看here 以供参考。

    【讨论】:

    • 我需要在用户按下后退按钮时显示警报。警报将具有“是”和“否”按钮。我在 viewWillDisappear 上试过了,但我的警报没有出现在它上面
    • 添加了另一个适合您情况的选项。
    • 它在视图出现时和每次推送时被调用,等等。我只想要它在后面。
    • @Nitesh 你必须检查将显示的viewController是否是你想要显示警报的那个,然后你就完成了!
    【解决方案5】:

    我认为这个answer 应该可以胜任。

    您基本上使用默认样式创建按钮并注册一个选择器。

    您可以尝试this 使用 backButton 而不是 leftButton:

    Objective-C

    UIBarButtonItem *backBtn = [[UIBarButtonItem alloc] init];
    [desVC.navigationItem setBackBarButtonItem:backBtn];
    

    斯威夫特

    let backBtn = UIBarButtonItem()
    self.navigationItem.backBarButtonItem = backBtn
    

    【讨论】:

      【解决方案6】:

      ParentViewControllerviewDidLoad 方法中调用这行代码而不是ChildViewController

      self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
      

      从您的ChildViewController 中删除以下代码行

      self.navigationItem.hidesBackButton = true
      

      你会没事的!如果您需要为此转换创建一个操作,我的意思是每当用户从您的ChildViewController 中点击返回按钮时。只需在 ChildViewController 中调用此方法

       override func didMove(toParentViewController parent: UIViewController?) {
          super.didMove(toParentViewController: parent)
      
          if parent == nil {
      
          } else {
      
          }
      }
      

      已编辑:

      ChildViewController

       override func didMove(toParentViewController parent: UIViewController?) {
          super.didMove(toParentViewController: parent)
      
          if parent == nil {
              NotificationCenter.default.post(name: NSNotification.Name.init("Post"), object: nil)
          } else {
      
          }
      
      }
      

      ParentViewController

       override func viewWillAppear(_ animated: Bool) {
          super.viewWillAppear(animated)
      
          NotificationCenter.default.addObserver(self, selector: #selector(self.handler(notification:)), name: NSNotification.Name.init(rawValue: "Post"), object: nil)
      
      }
      
      func handler(notification: Notification) {
      
          let alertController = UIAlertController(title: "Hello", message: nil, preferredStyle: .alert)
          alertController.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
          self.present(alertController, animated: true, completion: nil)
      
      }
      

      这是可行的,但有这样的问题:

      警告:在演示过程中尝试继续演示!

      所以不推荐。祝你好运

      【讨论】:

      • 但是这个警报视图没有呈现出来。
      • 但是这个alert会有点问题
      • 我这样做的主要目的是在按下返回时显示警报。
      • 我会告诉你的。但系统会警告您
      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2014-01-16
      • 1970-01-01
      相关资源
      最近更新 更多