PageView (UIPageViewController) 的条件同级中断分页
Posted
技术标签:
【中文标题】PageView (UIPageViewController) 的条件同级中断分页【英文标题】:Conditional sibling of a PageView (UIPageViewController) breaks paging 【发布时间】:2019-12-22 22:20:06 【问题描述】:我在 SwiftUI 中使用this UIPageViewController implementation 作为起点,但是当currentPage
是最后一页时,我希望有一个视图(例如:“OK”文本或按钮)出现在 PageView 的上方或下方。
但是,每当我在 PageView 上方或下方添加 if
语句时,只要我滑动到第二页,所有其他页面就会被删除,并且无法在页面之间滑动。如果我取出if
逻辑,一切正常。代码如下:
PageViewController:
struct PageViewController: UIViewControllerRepresentable
var controllers: [UIViewController]
@Binding var currentPage: Int
func makeCoordinator() -> Coordinator
Coordinator(self)
func makeUIViewController(context: Context) -> UIPageViewController
let pageViewController = UIPageViewController(
transitionStyle: .scroll,
navigationOrientation: .horizontal)
pageViewController.dataSource = context.coordinator
pageViewController.delegate = context.coordinator
return pageViewController
func updateUIViewController(_ pageViewController: UIPageViewController, context: Context)
var dir = UIPageViewController.NavigationDirection.forward
if let visibleViewController = pageViewController.viewControllers?.first,
let nextPage = controllers.firstIndex(of: visibleViewController)
if currentPage < nextPage
dir = .reverse
pageViewController.setViewControllers([controllers[currentPage]], direction: dir, animated: true)
class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate
var parent: PageViewController
init(_ pageViewController: PageViewController)
self.parent = pageViewController
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController?
guard let index = parent.controllers.firstIndex(of: viewController) else
return nil
if index == 0
return nil
return parent.controllers[index - 1]
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController?
guard let index = parent.controllers.firstIndex(of: viewController) else
return nil
if index + 1 == parent.controllers.count
return nil
return parent.controllers[index + 1]
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
if completed,
let visibleViewController = pageViewController.viewControllers?.first,
let index = parent.controllers.firstIndex(of: visibleViewController)
parent.currentPage = index
页面视图:
struct PageView<Page: View>: View
var viewControllers: [UIHostingController<Page>]
@Binding var currentPage: Int
init(_ views: [Page], currentPage: Binding<Int>)
self._currentPage = currentPage
self.viewControllers = views.map UIHostingController(rootView: $0)
var body: some View
PageViewController(controllers: viewControllers, currentPage: $currentPage).frame(width: UIScreen.main.bounds.width)
主内容视图:
struct TestView: View
@State private var curPage: Int = 0
var body: some View
ZStack
Color(.secondarySystemBackground)
VStack
if curPage == 9892832
Text("OK").padding().foregroundColor(.blue).padding(.top, 60)
PageView([
Text("Page 1"),
Text("Page 2"),
Text("Page 3"),
Text("Page 4")
], currentPage: $curPage)
.edgesIgnoringSafeArea(.all)
struct TestView_Previews: PreviewProvider
static var previews: some View
TestView()
我不知道这是 SwiftUI 错误还是使用 UIViewControllerRepresentable
的副作用或什么。有其他人看到这个带有条件视图吗?关于解决方法的任何想法?
【问题讨论】:
问题解决了吗?我尝试了第一个答案,但没有成功=(,我被这个问题困住了,我正在尝试第一个索引 这个问题你解决了吗? 【参考方案1】:我不知道这个问题的根本原因是什么。但我用两个嵌套的 VStack 解决了它。将您的 PageView 放在内部,并将您的 if 或其他视图放在外部 VStack 中。
VStack
if curPage == 9892832
Text("OK").padding().foregroundColor(.blue).padding(.top, 60)
VStack
PageView([
Text("Page 1"),
Text("Page 2"),
Text("Page 3"),
Text("Page 4")
], currentPage: $curPage)
【讨论】:
以上是关于PageView (UIPageViewController) 的条件同级中断分页的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中创建垂直滚动的 PageView?
在垂直PageView中包装不同高度的项目 - Flutter