我有一个 PageViewController,P,它包含两个子 ViewController,A 和 B。 A 和B 都允许用户在表单中输入一些数据。如果用户开始编辑表单,我会在一个 bool 变量中进行跟踪:
var formEdited = false;
如果用户想要离开表单,而 formEdited 为真,我想警告他们并说“您确定要放弃表单中的更改吗?”。如果他们确定,我想存储他们的数据。否则,我会让他们丢弃数据并继续刷卡。
因此,我尝试在 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);
}
}
因此,当我尝试从 View 中滑开时,我可以看到弹出窗口。如果我单击“取消”, View 仍然存在。 (这就是我想要的)但是,如果我再次尝试滑动,我将不再看到警告框,并且 UI 会发生变化。 (这不是我想要的。我希望它重新提示)
我相信我的代码需要在 viewWillDisappear 时做出更适当的 react 。我想我需要以某种方式防止 View 在上面这一行之后消失:
// TODO:: what to do here
注意:我试过其他一些帖子的答案,例如:How do I Disable the swipe gesture of UIPageViewController? , Disable swipe gesture in UIPageViewController ,甚至这两个:Disable UIPageViewController Swipe - Swift和 Checking if a UIViewController is about to get Popped from a navigation stack? .
最后两个可能是最合适的,但我不想禁用任何手势,也不知道如何注入(inject)预防措施。我只是想让从 subview 中滑出一个条件函数。我如何从 Swift 4 的 subview ( PageView 的 subview )执行此操作?
最佳答案
事实证明,在 UIPageView 中实现条件滚动操作是微不足道的。这些是我为解决问题而采取的步骤。 (鼓励更新此代码以使其更高效)
对于初学者来说,您的 UIPageViewController 不能是数据源。这意味着在 subview Controller 中的滚动操作期间,不会注册任何内容。 (现在没问题)相反,您希望实现显示 View 的逻辑,作为子项可以调用的函数。这两个方法可以添加到您的 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);
}
注意事项:
It would make sense to update the lines containing ?? 0; to a way to trow an error, or show some default screen.
orderedViewControllers is a list of all child views that this UIPageView controller contains
These methods will be called from child views, so keeping them at this layer makes them very reusable
最后,在您的 subview 中,您需要一种识别手势并对手势使用react的方法:
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);
}
}
注意事项:
In handleGesture function, you'd add your conditional checks to determine if goToNextView or goToPreviousView is ok.
关于ios - PageView 中 subview 之间的条件更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55974149/