如何在 SwiftUI 中的 PageViewController 中传递一些视图?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中的 PageViewController 中传递一些视图?【英文标题】:How to pass some views in PageViewController in SwiftUI? 【发布时间】:2020-05-04 10:19:08 【问题描述】:在我的 SwiftUI 应用程序中,当我尝试在 PageViewController 中传递一些视图时出现错误。我不明白他们想要什么意思。我用经典的方式设置了这样的 PageViewController:
PageViewController 文件:
import Foundation
import UIKit
import SwiftUI
struct PageViewController: UIViewControllerRepresentable
@Binding var currentPageIndex: Int
@EnvironmentObject var viewData: ViewData
var viewControllers: [UIViewController]
func makeCoordinator() -> Coordinator
Coordinator(self)
func makeUIViewController(context: Context) -> UIPageViewController
let pageViewController = UIPageViewController(
transitionStyle: .scroll,
navigationOrientation: .horizontal,
options: [UIPageViewController.OptionsKey.interPageSpacing : self.viewData.pageViewControllerPadding]
)
pageViewController.dataSource = context.coordinator
pageViewController.delegate = context.coordinator
let compassScreen = viewControllers[0]
let sonarScreen = viewControllers[1]
compassScreen.view.backgroundColor = UIColor.clear
sonarScreen.view.backgroundColor = UIColor.clear
return pageViewController
func updateUIViewController(_ pageViewController: UIPageViewController, context: Context)
pageViewController.setViewControllers(
[viewControllers[currentPageIndex]], direction: currentPageIndex == 0 ? .reverse : .forward, animated: true
)
class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate
var parent: PageViewController
init(_ pageViewController: PageViewController)
self.parent = pageViewController
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
// Retrieves the index of the currently displayed view controller
guard let index = parent.viewControllers.firstIndex(of: viewController) else
return nil
// Shows the last view controller when the user swipes back from the first view controller
if index == 0
return nil
// Show the view controller before the currently displayed view controller
return parent.viewControllers[index - 1]
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
// Retrieves the index of the currently displayed view controller
guard let index = parent.viewControllers.firstIndex(of: viewController) else
return nil
// Shows the first view controller when the user swipes further from the last view controller
if index + 1 == parent.viewControllers.count
return nil
// Show the view controller after the currently displayed view controller
return parent.viewControllers[index + 1]
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
if completed, let visibleViewController = pageViewController.viewControllers?.first, let index = parent.viewControllers.firstIndex(of: visibleViewController)
parent.currentPageIndex = index
PageView 文件:
import SwiftUI
struct PageView<Page: View>: View
@State var currentPage = 0
var viewControllers: [UIHostingController<Page>]
init(_ views: [Page])
self.viewControllers = views.map UIHostingController(rootView: $0)
var body: some View
VStack(alignment: .center)
PageViewController(
currentPageIndex: $currentPage,
viewControllers: viewControllers
)
还有我的 contentView 文件,我尝试像这样传递我的观点:
import SwiftUI
import CoreLocation
@EnvironmentObject var settingsStore: SettingsStore
@EnvironmentObject var userData: UserData
struct ContentView: View
var body: some View
VStack()
PageView([
Compass()
.padding(.bottom, 10)
.environmentObject(settingsStore)
.environmentObject(userData)
Sonar()
.padding(.bottom, 10)
.environmentObject(settingsStore)
.environmentObject(userData)
])
PageView(...)
行出现此错误:
我试着把这个:
PageView([
UIHostingController(rootView: Compass()
.padding(.bottom, 10)
.environmentObject(settingsStore)
.environmentObject(userData)
),
UIHostingController(rootView: Sonar()
.padding(.bottom, 10)
.environmentObject(settingsStore)
.environmentObject(userData)
)
])
但是我又报错了:
我不知道该怎么办?
【问题讨论】:
【参考方案1】:问题在于,当您应用修饰符时,生成的视图不再是 Compass(或 Page)类型,而是变成“某些视图”,请看:https://developer.apple.com/documentation/swiftui/view/padding(_:_:)
因此,您不能创建这样的数组。相反,您应该将您的数组元素类型擦除到 AnyView(AnyView(Compass().padding())
),并将您的数组元素类型修改为 UIHostingController<AnyView>
【讨论】:
以上是关于如何在 SwiftUI 中的 PageViewController 中传递一些视图?的主要内容,如果未能解决你的问题,请参考以下文章
如何知道 UIKit 视图控制器中的 swiftUI 事件? ||如何提供 swiftUI 和 uikit 之间的通信
如何在 SwiftUI 中的 PageViewController 中传递一些视图?