SwiftUI UIPageView 编译错误和操作表问题

Posted

技术标签:

【中文标题】SwiftUI UIPageView 编译错误和操作表问题【英文标题】:SwiftUI UIPageView compile error and action sheet problem 【发布时间】:2019-12-09 13:37:54 【问题描述】:

我的代码中有 2 个问题。

一个是编译错误[无法将类型'Page1'的值转换为预期的元素类型'_']显示在★。

另一个是当按下后退按钮时,Page2(蓝色)在显示警报表时消失。 (注释掉“Page1(page: self.$page)”,然后构建源代码) 预期的行为是 Page2(蓝色)在按下警报按钮(是)之前不会消失。

谁能告诉我如何解决这些问题?

import SwiftUI

struct PageViewController: UIViewControllerRepresentable 
    var controllers: [UIViewController]
    @Binding var currentPage: Int

    func makeCoordinator() -> Coordinator 
        Coordinator(self)
    

    func makeUIViewController(context: Context) -> UIPageViewController 
        let pageViewController = UIPageViewController(
            transitionStyle: .pageCurl,
            navigationOrientation: .vertical)
        pageViewController.dataSource = context.coordinator
        pageViewController.delegate = context.coordinator

        return pageViewController
    

    func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) 
        pageViewController.setViewControllers(
            [controllers[currentPage]], direction: .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?
        
            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)
    



struct ContentView: View 
    @State var page: Int = 0

    var body: some View 
        VStack 
            PageView([
                Page1(page: self.$page), // ★ error
                Page2(page: self.$page)// ★ error
            ], currentPage: $page)
        
    



struct Page1: View
    @Binding var page: Int
    var body: some View 
        ZStack
            Color.red
            VStack
                Text("page1")
                Button (
                    action:  self.page += 1 
                )
                    Image(systemName: "forward")
                        .accentColor(Color.yellow)
                
            
        
    



struct Page2: View
    @State private var showingAlert: Bool = false
    @Binding var page: Int
    var body: some View 
        ZStack
            Color.blue
            VStack
                Text("page2")
                Button (
                    action:  self.showingAlert.toggle() 
                )
                    Image(systemName: "backward")
                        .accentColor(Color.yellow)
                
            
            .alert(isPresented: $showingAlert) 
                Alert(
                    title: Text("Confirm"),
                    message: Text("Back?"),
                    primaryButton:
                    .default(Text("Yes"),
                             action: self.page -= 1 
                    ),
                    secondaryButton:
                    .cancel(Text("No"))
                )//alert
            //alert
        
    

【问题讨论】:

这样使用 ★ 错误 "PageView([AnyView(Page1(page: $page)), AnyView(Page2(page: $page))], currentPage: $page)" 可能有效但不确定只试一次。 谢谢!有用。但第二个问题仍然存在。显示警报表时行为很奇怪。你知道怎么解决吗? 我只是运行您的代码,不知道这种奇怪的行为,但我建议将自定义视图作为弹出窗口而不是警报打开。有帮助,请点赞评论。 【参考方案1】:

我能够使用:

[如何在 SwiftUI #1 中创建引导屏幕 - 嵌入 UIPageViewController] (https://www.blckbirds.com/post/how-to-create-a-onboarding-screen-in-swiftui-1)

【讨论】:

以上是关于SwiftUI UIPageView 编译错误和操作表问题的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 编译器错误:编译器无法在合理的时间内对该表达式进行类型检查(Xcode 12.0 SwiftUI)

SwiftUI ForEach Binding 编译时错误看起来不像 for-each

SwiftUI在我更改图像形状后无法编译

UITableView 比 UIPageView 内的屏幕大

在 SwiftUI 视图中设置计算属性无法编译

将 UIPageView 添加为屏幕的一部分