如何在Swift中使用UIPageViewController在所有viewcontroller中显示相同的顶层设计

rjee0c15  于 10个月前  发布在  Swift
关注(0)|答案(1)|浏览(100)

我已经在MainSegPageViewController中创建了像这样的故事板顶层设计,我还有另外两个视图控制器。现在我需要在我的所有三个视图控制器相同的上层设计。那么如何只在这个权重区域显示2个视图控制器呢?有可能吗?如果是,请解释

**code:**使用此代码最初我得到ViewController1为什么?如何显示MainSegPageViewController初始?以及如何显示ViewController1在白色区域当我点击STEP 2.请给我指路。

import UIKit

class MainSegPageViewController: UIPageViewController {

private(set) lazy var subViewcontrollers: [UIViewController] = {
    return [
        UIStoryboard(name: "Main", bundle: nil) .
        instantiateViewController(withIdentifier: "ViewController1"),
        UIStoryboard(name: "Main", bundle: nil) .
        instantiateViewController(withIdentifier: "ViewController2")
    ]
}()

override func viewDidLoad() {
    super.viewDidLoad()
    dataSource = self
    modalPresentationStyle = .formSheet

   if let firstViewController = subViewcontrollers.first {
        setViewControllers([firstViewController],
                           direction: .forward,
                           animated: true,
                           completion: nil)
    }

    setUpNavigationBar(with: "Pagination vc", isBackNeed: true)
    self.navigationController?.navigationBar.isHidden = false
    
}
}

// MARK: UIPageViewControllerDataSource
extension MainSegPageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    guard let viewControllerIndex = subViewcontrollers.firstIndex(of:viewController) 
 else {
        return nil
    }
    let previousIndex = viewControllerIndex - 1
    guard previousIndex >= 0 else {
        return nil
    }
    guard subViewcontrollers.count > previousIndex else {
        return nil
    }
    if previousIndex == 2 {
        return nil
    }
    return subViewcontrollers[previousIndex]
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    guard let viewControllerIndex = subViewcontrollers.firstIndex(of:viewController) 
 else {
        return nil
    }
    let nextIndex = viewControllerIndex + 1
    let orderedViewControllersCount = subViewcontrollers.count
    
    guard orderedViewControllersCount != nextIndex else {
        return nil
    }
    guard orderedViewControllersCount > nextIndex else {
        return nil
    }
    if nextIndex == 3 {
        return nil
    }
    return subViewcontrollers[nextIndex]
}
func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return subViewcontrollers.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
    guard let firstViewController = viewControllers?.first, let firstViewControllerIndex = subViewcontrollers.firstIndex(of: firstViewController) else {
        return 0
    }
    return firstViewControllerIndex
}
}

我通过侧菜单到达MainSegPageViewController,如下所示

let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "MainSegPageViewController") as? MainSegPageViewController
        self.navigationController?.pushViewController(vc!, animated: true)

**o/p:**与代码最初我得到ViewController1屏幕,但我需要MainSegPageViewController显示第一。

4nkexdtk

4nkexdtk1#

要实现您的布局,一种方法是创建一个包含“Welcome to Profile”标签和UISegmentedControl的“Profile”视图控制器,然后将UIPageViewController嵌入到容器视图中。
所以,既然你的帖子说你在导航控制器中推到这个布局,我们就从故事板开始:

按钮将连接到以下代码:

@IBAction func profileButtonTapped(_ sender: Any) {
    if let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ProfileViewController") as? ProfileViewController {
        navigationController?.pushViewController(vc, animated: true)
    }
}

然后,像这样在Storyboard中布局ProfileViewController

大视图为UIContainerView

我们在里面嵌入了一个典型的UIPageViewController
假设你有页面视图控制器的工作代码,这可以运行,你就可以在页面上来回滑动。
接下来,我们需要添加一些代码,以便点击Segment将更改页面。
我们可以这样设置ProfileViewController

class ProfileViewController: UIViewController {
    
    @IBOutlet var stepsSegCtrl: UISegmentedControl!
    
    // we will want a reference to the embedded MainSegPageViewController
    //  so we can tell it to change page when the segmented control is tapped
    var mainSegPageVC: MainSegPageViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Pagination VC"
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // this is called because we've embedded the controller in a container view
        if let pgVC = segue.destination as? MainSegPageViewController {
            // save reference so we can access it when the segmented control is tapped
            mainSegPageVC = pgVC
        }
    }
    
    @IBAction func segCtrlChanged(_ sender: UISegmentedControl) {
        // safely unwrap
        if let pgVC = mainSegPageVC {
            pgVC.gotoPage(pg: sender.selectedSegmentIndex)
        }
    }
    
}

当在容器视图中嵌入控制器时,我们会自动获得一个segue,在这里我们可以获取对嵌入的页面视图控制器的引用。
如果我们将这个函数添加到MainSegPageViewController类中:

public func gotoPage(pg: Int) {
    let curPg = presentationIndex(for: self)
    if pg > curPg {
        setViewControllers([subViewcontrollers[pg]],
                           direction: .forward,
                           animated: true,
                           completion: nil)
    } else {
        setViewControllers([subViewcontrollers[pg]],
                           direction: .reverse,
                           animated: true,
                           completion: nil)
    }
}

我们现在可以从分段控件更改页面。
最后,我们需要添加一个closure,这样当用户拖动到一个新页面时,页面视图控制器可以通知“父”控制器。
因此,在MainSegPageViewController类中,我们添加以下属性:

var pageChanged: ((Int) -> ())?

并实施:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    // user dragged to a new page, so inform the parent controller
    pageChanged?(presentationIndex(for: self))
}

我们将ProfileViewController中的闭包设置回prepare(for segue:...)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // this is called because we've embedded the controller in a container view
    if let pgVC = segue.destination as? MainSegPageViewController {
        // set the closure
        pgVC.pageChanged = { [weak self] pg in
            guard let self = self else { return }
            // user dragged to a new page, so update the segmented control
            self.stepsSegCtrl.selectedSegmentIndex = pg
        }
        // save reference so we can access it when the segmented control is tapped
        mainSegPageVC = pgVC
    }
}

我在这里展示了一个完整的项目-https://github.com/DonMag/ContainerPageViewController,这样您就可以在构建自己的项目时检查代码和情节串联图板-并查看实际操作。

相关问题