Ios 以编程方式创建部分屏幕UIPageViewController

Ios 以编程方式创建部分屏幕UIPageViewController,ios,swift,uiscrollview,uipageviewcontroller,Ios,Swift,Uiscrollview,Uipageviewcontroller,我正在尝试创建一个只占用部分屏幕的滚动页面视图控制器。我已经使用Storyboard和ContainerView对象成功地完成了这项工作,但是我现在需要以编程方式复制创建项目的功能 似乎ContainerView不是我可以使用swift创建的,所以我尝试使用UIView作为容器来创建它,我尝试使用UIPageViewController添加子视图,但是我得到错误无法将UIPageViewController类型的值转换为预期的参数类型UIView 我想我这里一定缺少了一些简单的东西,因为正如我所

我正在尝试创建一个只占用部分屏幕的滚动页面视图控制器。我已经使用Storyboard和ContainerView对象成功地完成了这项工作,但是我现在需要以编程方式复制创建项目的功能

似乎ContainerView不是我可以使用swift创建的,所以我尝试使用UIView作为容器来创建它,我尝试使用UIPageViewController添加子视图,但是我得到错误
无法将UIPageViewController类型的值转换为预期的参数类型UIView


我想我这里一定缺少了一些简单的东西,因为正如我所说的,我已经用故事板/界面生成器实现了这一点,但是如何在使用Swift以编程方式构建时获得类似的功能呢?

UIContainerView
实际上只是一个故事板的便利。它添加了一个普通的
UIView
,并允许您连接一个视图控制器作为其“嵌入内容”

但是,在引擎盖下,它正是您可以从代码中执行的操作:

  • ui视图
    添加到将用作“容器”的主视图中
  • 实例化页面视图控制器
  • 使用
    addChild(\uchildcontroller:UIViewController)
    将该页面视图控制器添加为子控制器
  • 将子VC视图添加到“容器”视图中
下面是一个完整的示例:

//
//  Created by Don Mag on 5/31/19.
//

import UIKit

// simple example view controller
// has a label 90% of the width, centered X and Y
class ExampleViewController: UIViewController {

    let theLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .white
        v.textAlignment = .center
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(theLabel)
        NSLayoutConstraint.activate([
            theLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            theLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            theLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
            ])

    }

}

// example Page View Controller
class MyPageViewController: UIPageViewController {

    let colors: [UIColor] = [
        .red,
        .green,
        .blue,
        .cyan,
        .yellow,
        .orange
    ]

    var pages: [UIViewController] = [UIViewController]()

    override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        dataSource = self
        delegate = nil

        // instantiate "pages"
        for i in 0..<colors.count {
            let vc = ExampleViewController()
            vc.theLabel.text = "Page: \(i)"
            vc.view.backgroundColor = colors[i]
            pages.append(vc)
        }

        setViewControllers([pages[0]], direction: .forward, animated: false, completion: nil)
    }

}

// typical Page View Controller Data Source
extension MyPageViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = pages.index(of: viewController) else { return nil }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else { return pages.last }

        guard pages.count > previousIndex else { return nil }

        return pages[previousIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = pages.index(of: viewController) else { return nil }

        let nextIndex = viewControllerIndex + 1

        guard nextIndex < pages.count else { return pages.first }

        guard pages.count > nextIndex else { return nil }

        return pages[nextIndex]
    }
}

// typical Page View Controller Delegate
extension MyPageViewController: UIPageViewControllerDelegate {

    // if you do NOT want the built-in PageControl (the "dots"), comment-out these funcs

    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return pages.count
    }

    func presentationIndex(for pageViewController: UIPageViewController) -> Int {

        guard let firstVC = pageViewController.viewControllers?.first else {
            return 0
        }
        guard let firstVCIndex = pages.index(of: firstVC) else {
            return 0
        }

        return firstVCIndex
    }
}

class MyTestViewController: UIViewController {

    let myContainerView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .gray
        return v
    }()

    var thePageVC: MyPageViewController!

    override func viewDidLoad() {
        super.viewDidLoad()

        // add myContainerView
        view.addSubview(myContainerView)

        // constrain it - here I am setting it to
        //  40-pts top, leading and trailing
        //  and 200-pts height
        NSLayoutConstraint.activate([
            myContainerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40.0),
            myContainerView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            myContainerView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            myContainerView.heightAnchor.constraint(equalToConstant: 200.0),
            ])

        // instantiate MyPageViewController and add it as a Child View Controller
        thePageVC = MyPageViewController()
        addChild(thePageVC)

        // we need to re-size the page view controller's view to fit our container view
        thePageVC.view.translatesAutoresizingMaskIntoConstraints = false

        // add the page VC's view to our container view
        myContainerView.addSubview(thePageVC.view)

        // constrain it to all 4 sides
        NSLayoutConstraint.activate([
            thePageVC.view.topAnchor.constraint(equalTo: myContainerView.topAnchor, constant: 0.0),
            thePageVC.view.bottomAnchor.constraint(equalTo: myContainerView.bottomAnchor, constant: 0.0),
            thePageVC.view.leadingAnchor.constraint(equalTo: myContainerView.leadingAnchor, constant: 0.0),
            thePageVC.view.trailingAnchor.constraint(equalTo: myContainerView.trailingAnchor, constant: 0.0),
            ])

        thePageVC.didMove(toParent: self)
    }

}
//
//Don Mag于19年5月31日创建。
//
导入UIKit
//简单示例视图控制器
//标签的宽度为90%,以X和Y为中心
类示例ViewController:UIViewController{
让标签:UILabel={
设v=UILabel()
v、 translatesAutoresizingMaskIntoConstraints=false
v、 背景颜色=白色
v、 textAlignment=.center
返回v
}()
重写func viewDidLoad(){
super.viewDidLoad()
视图。添加子视图(标签)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(等于:view.centerXAnchor),
label.centerYAnchor.constraint(等式:view.centerYAnchor),
label.widthAnchor.constraint(等式:view.widthAnchor,乘数:0.9),
])
}
}
//页面视图控制器示例
类MyPageViewController:UIPageViewController{
让颜色:[UIColor]=[
红色
绿色
蓝色
青色先生,
黄先生,
橙色
]
变量页:[UIViewController]=[UIViewController]()
重写初始化(transitionStyle:UIPageViewController.transitionStyle,navigationOrientation:UIPageViewController.navigationOrientation,选项:[UIPageViewController.OptionKey:Any]?=nil){
super.init(transitionStyle:.滚动,navigationOrientation:.水平,选项:nil)
}
必需初始化?(编码器:NSCoder){
super.init(编码器:编码器)
}
重写func viewDidLoad(){
super.viewDidLoad()
数据源=self
委托=零
//实例化“页面”
对于0..UIViewController中的i{
guard let viewControllerIndex=pages.index(of:viewController)else{return nil}
让previousIndex=viewControllerIndex-1
guard previousIndex>=0 else{return pages.last}
guard pages.count>previousIndex else{return nil}
返回页面[以前的索引]
}
func pageViewController(pageViewController:UIPageViewController,viewController后的viewController:UIViewController)->UIViewController{
guard let viewControllerIndex=pages.index(of:viewController)else{return nil}
设nextIndex=viewControllerIndex+1
guard nextIndexnextIndex else{return nil}
返回页面[nextIndex]
}
}
//典型的页视图控制器委托
扩展名MyPageViewController:UIPageViewControllerDelegate{
//如果您不想要内置的页面控件(“点”),请注释掉这些函数
func presentationCount(对于pageViewController:UIPageViewController)->Int{
返回页数.count
}
func presentationIndex(对于pageViewController:UIPageViewController)->Int{
guard let firstVC=pageViewController.ViewController{
返回0
}
guard let firstVCIndex=pages.index(of:firstVC)else{
返回0
}
返回第一个索引
}
}
类MyTestViewController:UIViewController{
让myContainerView:UIView={
设v=UIView()
v、 translatesAutoresizingMaskIntoConstraints=false
v、 背景颜色=.灰色
返回v
}()
var thePageVC:MyPageViewController!
重写func viewDidLoad(){
super.viewDidLoad()
//添加myContainerView
view.addSubview(myContainerView)
//约束它-在这里我将其设置为
//40分顶部、前部和尾部
//和200分高
NSLayoutConstraint.activate([
myContainerView.topAnchor.constraint(等式:view.safeAreaLayoutGuide.topAnchor,常量:40.0),
myContainerView.leadingAnchor.constraint(等式:view.SafeArealLayoutGuide.leadingAnchor,常量:40.0),
myContainerView.trailingAnchor.constraint(等式:view.SafeArealLayoutGuide.trailingAnchor,常数:-40.0),
myContainerView.heightAnchor.constraint(相等常量:200.0),
])
//实例化MyPageViewController并将其添加为子视图控制器
thePageVC=MyPageViewController()
addChild(页面VC)
//我们需要重新调整页面视图控制器视图的大小,以适合容器视图
page vc.view.translates自动调整大小GMaskintoConstraints=false
//将页面VC的视图添加到我们的容器视图中
myContainerView.addSubview(页面VC.view)
//将其约束到所有4个边
NSLayoutCons