PageView中的子视图之间的条件更改

时间:2019-05-03 16:50:26

标签: ios swift user-interface

我有一个PageViewController, P ,其中包含两个子ViewController, A B A B 都允许用户在表单中输入一些数据。如果用户开始编辑表单,我将跟踪一个布尔变量:

var formEdited = false;

如果用户想离开表单,并且formEdited为true,我想警告他们并说:“您确定要放弃表单中的更改吗?”。如果他们确定,我想存储他们的数据。否则,我会让他们丢弃数据并继续刷卡。

结果,我尝试在 A B 中执行以下操作:

 override func viewWillDisappear(_ animated: Bool) {
    if (formEdited) {
        let dialogMessage = UIAlertController(title: "Confirm", message: "Are you sure you want to abandon the changes you have in the form?", preferredStyle: .alert);
        let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
            super.viewWillDisappear(animated);
        })
        let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
            // TODO:: what to do here
            self.myCustomFuctionToStoreData(); 
            super.viewWillAppear(true);

        }
        dialogMessage.addAction(ok);
        dialogMessage.addAction(cancel);
        self.present(dialogMessage, animated: true, completion: nil);
    }
}

结果是,当我尝试从“视图”滑开时,我可以看到我的弹出窗口。如果单击“取消”,则视图仍然存在。 (这是我想要的)但是,如果我再次尝试再次滑动,将不再看到警报框,并且UI也会更改。 (这不是我想要的。我希望它再次提示)

我认为当viewWillDisappear出现时,我的代码需要做出更适当的反应。我想我需要以某种方式防止视图在上面的这一行之后消失:

// TODO:: what to do here

注意:我已经尝试了其他一些帖子的答案,例如:How do I Disable the swipe gesture of UIPageViewController?Disable swipe gesture in UIPageViewController,甚至是这两个帖子:Disable UIPageViewController Swipe - SwiftChecking if a UIViewController is about to get Popped from a navigation stack?

最后两个可能是最合适的,但是我不想禁用任何手势,也不想看到如何注入预防措施。我只是想使从子视图的滑动成为条件函数。如何在Swift 4的子视图(PageView的子视图)中做到这一点?

1 个答案:

答案 0 :(得分:0)

事实证明,在UIPageView中实现条件滚动操作是微不足道的。这些是我为解决问题所采取的步骤。 (鼓励对此代码进行更新以使其更高效)

对于初学者,您的UIPageViewController不得为dataSource。这意味着在子视图控制器中进行滚动操作时,不会进行任何注册。 (现在可以了)相反,您希望实现逻辑,以便在子视图可以调用的函数时显示视图。可以将这两种方法添加到您的UIPageView中:

func goToNextView(currentViewController : UIViewController) {
    var movingIdx = 0;
    let viewControllerIndex = orderedViewControllers.index(of: currentViewController) ?? 0;
    if (viewControllerIndex + 1 <= (orderedViewControllers.count - 1)) {
        movingIdx = viewControllerIndex + 1;
    }
    self.setViewControllers([orderedViewControllers[movingIdx]], direction: .forward, animated: true, completion: nil);
}

func goToPreviousView(currentViewController : UIViewController) {
    var movingIdx = 0;
    let viewControllerIndex = orderedViewControllers.index(of: currentViewController) ?? -1;
    if (viewControllerIndex == -1) {
        movingIdx = 0;
    } else if (viewControllerIndex - 1 >= 0) {
        movingIdx = viewControllerIndex - 1;
    } else {
        movingIdx = orderedViewControllers.count - 1;
    }
    self.setViewControllers([orderedViewControllers[movingIdx]], direction: .reverse, animated: true, completion: nil);
}

注意:

  

更新包含??的行是有意义的0;引发错误或显示某些默认屏幕的方式。

     

orderedViewControllers是此UIPageView控制器包含的所有子视图的列表

     

这些方法将从子视图中调用,因此将它们保留在这一层将使其非常可重用

最后,在子视图中,您需要一种识别手势并对手势做出反应的方法:

override func viewDidLoad() {
    super.viewDidLoad();

    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeLeft.direction = .left
    self.view.addGestureRecognizer(swipeLeft)

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
    swipeRight.direction = .right
    self.view.addGestureRecognizer(swipeRight)

}

处理手势:

@objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
    if gesture.direction == UISwipeGestureRecognizerDirection.left {
        parentPageViewController.goToNextView(currentViewController: self);
    }
    else if gesture.direction == UISwipeGestureRecognizerDirection.right {
        parentPageViewController.goToPreviousView(currentViewController: self);
    }
}

注意:

  

在handleGesture函数中,您将添加条件检查以确定goToNextView或goToPreviousView是否可以。