【问题标题】:How to pass some views in PageViewController in SwiftUI?如何在 SwiftUI 中的 PageViewController 中传递一些视图?
【发布时间】: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)
   )
 ])

但是我又报错了:

我不知道该怎么办?

【问题讨论】:

    标签: swift swiftui uipageviewcontroller


    【解决方案1】:

    问题在于,当您应用修饰符时,生成的视图不再是 Compass(或 Page)类型,而是变成“某些视图”,请看:https://developer.apple.com/documentation/swiftui/view/padding(_:_:)

    因此,您不能创建这样的数组。相反,您应该将您的数组元素类型擦除到 AnyView(AnyView(Compass().padding())),并将您的数组元素类型修改为 UIHostingController&lt;AnyView&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      相关资源
      最近更新 更多