Create partial-screen UIPageViewController programmatically(以编程方式创建部分屏幕 UIPageViewController)
问题描述
我正在尝试创建一个只占用部分屏幕的滚动页面视图控制器.我已经使用 Storyboard 和 ContainerView 对象成功完成了这项工作,但我现在需要复制以编程方式创建项目的功能.
I am trying to create a scrolling pageviewcontroller that only takes up part of my screen. I have successfully done this using Storyboard and a ContainerView object, but I now need to replicate the functionality creating the project programmatically.
似乎 ContainerView 不是我可以使用 swift 创建的东西,所以我尝试使用 UIView 作为容器来执行此操作,我尝试使用 UIPageViewController 执行 addSubview,但我收到错误 cannot将 UIPageViewController 类型的值转换为预期的参数类型 UIView.
It seems that ContainerView is not something that I can create using swift, so I tried to do this using a UIView to act as a container that I tried to do addSubview with a UIPageViewController, but I get the error cannot convert value of type UIPageViewController to expected argument type UIView.
我认为我必须在这里遗漏一些简单的东西,因为正如我所说,我已经使用 Storyboard/Interface Builder 完成了这一点,但是如何在使用 Swift 以编程方式构建时获得类似的功能?
I assume that I must be missing something simple here, since as I said, I've accomplished this with Storyboard/Interface Builder, but how can I get similar functionality while building programmatically with Swift?
推荐答案
UIContainerView 实际上只是一个 Storyboard 的便利.它添加了一个普通的 UIView 并允许你连接一个 View Controller 作为它的嵌入内容".
UIContainerView is really just a Storyboard convenience. It adds a normal UIView and allows you to connect a View Controller as its "embedded content."
但是,在幕后,它正在做你可以通过代码做的事情:
But, under the hood, it is doing exactly what you can do from code:
- 将
UIView添加到您将用作容器"的主视图中 - 实例化您的页面视图控制器
- 使用
addChild(_ childController: UIViewController)将该页面视图控制器添加为子控制器 - 将子 VC 的视图添加到您的容器"视图中
- add a
UIViewto your main view that you will use as the "container" - instantiate your page view controller
- use
addChild(_ childController: UIViewController)to add that page view controller as a child controller - add the child VC's view to your "container" view
这是一个完整的例子:
//
// 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)
}
}
结果:
这篇关于以编程方式创建部分屏幕 UIPageViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:以编程方式创建部分屏幕 UIPageViewController
基础教程推荐
- 如何从 logcat 中删除旧数据? 2022-01-01
- navigator.geolocation.getCurrentPosition 在 Android 浏览器上 2022-01-01
- iOS4 创建后台定时器 2022-01-01
- Android:getLastKnownLocation(LocationManager.NETWORK_PROVIDER 2022-01-01
- AdMob 广告未在模拟器中显示 2022-01-01
- Cocos2d iPhone 非矩形精灵触摸检测 2022-01-01
- libGDX 从精灵或纹理中获取像素颜色 2022-01-01
- iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法 2022-01-01
- NSString intValue 不能用于检索电话号码 2022-01-01
- 通过重定向链接在 Google Play 中打开应用 2022-01-01
