仅当通过滑动或后退按钮弹出视图控制器时才发送数据,但不能通过切换选项卡

时间:2017-06-12 11:01:52

标签: swift uiviewcontroller uinavigationcontroller swipe back-button

我查看了SO并在下面编译了这些方法,但它们都不适用于我。

我有一个带有2个标签的TabBarController。在第二个标签中,我有一个NavigationController> TableViewController> DetailViewController。

在我的DetailViewController中,我有一个自定义委托,当按下后退按钮或视图被滑动到解除时(向右滑动),将一些数据发送到TableViewController。我只希望当后退按钮或滑动到完全关闭时发送的数据完全结束,并且在切换选项卡时没有发送数据,或者如果向右滑动但是用户决定不完成后滑动(基本上它们保持打开状态)相同的DetailVC场景。)

我在下面尝试了所有这些方法,当Tab切换到第一个标签时,当DetailVC被推开并弹出时,或者在1/2方式滑动以解除DetailVC时,它们会被触发意思是不应该发送数据。

DetailViewController:

protocol DetailViewDelegate: class {
    func sendSomeData(value: Bool)
}

class DetailViewController: UIViewController{

weak var delegate: DetailViewDelegate?

//1. runs when Tab switches, the Back Button is pressed, and Swipe to Dismiss is triggered
override func viewWillDisappear(_ animated : Bool) {
        super.viewWillDisappear(animated)
        if (self.isMovingFromParentViewController) || (self.isBeingDismissed){
            //doesn't run at all
        }else{
            //runs whenever view is no longer on scene
            sendData()
        }
    }

//2. runs when Tab switches, Back Button is pressed, Swipe to Dismiss is triggered, and when the view is Pushed on AND Popped off
override func didMove(toParentViewController parent: UIViewController?) {
        if parent != nil {
            sendData()
        }else{
            //if parent == nil doesn't run at all
        }
    }

//3. if switching from the second tab it doesn't run but when switching back to the second tab it does run, also runs when view is being Pushed on and Not Popped on
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
         sendData()
    }

//4. if switching from the second tab it doesn't run but when switching back to the second tab it does run, also runs when view is being Pushed on and Not Popped on
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
         sendData()
    }

//MARK:- Custom Func
    fileprivate func sendData(){
        let value = true
        delegate?.sendSomeData(value: value)
    }
}

TableViewController:

class TableVC: UIViewController, DetailViewDelegate, UITableViewData..., UITableViewDele...{

var setValue = false

func sendSomeData(value: Bool){

     //setValue should only update to true if DetailVC's Back Button is pressed or Right Swipe to Dismiss is fully complete
     self.setValue = value
}

}

TableView从未遇到过接收数据的问题。问题是当我切换标签(数据仍然被发送)或者在DetailVC上轻扫时没有完全完成(数据仍然被发送)。

从DetailVC发送数据但确保按下后退按钮或右滑动到解除的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

您需要使用自定义后退按钮和委托来呼叫父级。 这是你的父ViewController:

import UIKit

class ViewController: UIViewController, ViewControllerSecondDelegate {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "Next" {
            let vc = segue.destination as? ViewControllerSecond
            vc?.delegate = self
        }
    }

    func secondDelegate() {
        print("delegate") //GetData()
    }

}

这是子视图控制器,您要将其从它返回到您的父级:

import UIKit

protocol ViewControllerSecondDelegate {
    func secondDelegate()
}

class ViewControllerSecond: UIViewController, UIGestureRecognizerDelegate {

    var isTouched = false
    var isPopTouch = true
    var delegate: ViewControllerSecondDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.setNavigationBarHidden(false, animated:false)
        let myBackButton:UIButton = UIButton.init(type: .custom)
        myBackButton.addTarget(self, action: #selector(ViewControllerSecond.popToRoot(sender:)), for: .touchUpInside)
        myBackButton.setTitle("Back", for: .normal)
        myBackButton.setTitleColor(.blue, for: .normal)
        myBackButton.sizeToFit()
        let myCustomBackButtonItem:UIBarButtonItem = UIBarButtonItem(customView: myBackButton)
        self.navigationItem.leftBarButtonItem  = myCustomBackButtonItem
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if isTouched {
            isPopTouch = true
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.isPopTouch = false
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        if isPopTouch {
            delegate?.secondDelegate()
        }
    }

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
            self.isTouched = true
        }
        return true
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.isTouched = false
    }

    func popToRoot(sender:UIBarButtonItem){
        delegate?.secondDelegate()
        self.navigationController?.popToRootViewController(animated: true)
    }

}

上面的代码,处理后退按钮和后退手势。