gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 08:13:56 26 4
gpt4 key购买 nike

我正在尝试创建一个只占据屏幕一部分的滚动页面 View Controller 。我已经使用 Storyboard 和 ContainerView 对象成功地做到了这一点,但我现在需要复制以编程方式创建项目的功能。

似乎 ContainerView 不是我可以使用 swift 创建的东西,所以我尝试使用 UIView 来充当我尝试使用 UIPageViewController 执行 addSubview 的容器来执行此操作,但我收到错误 cannot将 UIPageViewController 类型的值转换为预期的参数类型 UIView

我想我一定在这里遗漏了一些简单的东西,因为正如我所说,我已经使用 Storyboard/Interface Builder 完成了这个,但是我如何才能在使用 Swift 以编程方式构建时获得类似的功能?

最佳答案

UIContainerView 实际上只是 Storyboard 的便利。它添加了一个普通的 UIView 并允许您连接一个 View Controller 作为它的“嵌入内容”。

但是,在幕后,它正在执行您可以通过代码执行的操作:

  • UIView 添加到您将用作“容器”的主视图
  • 实例化您的页面 View Controller
  • 使用 addChild(_ childController: UIViewController) 将该页面 View Controller 添加为子 Controller
  • 将子 VC 的 View 添加到您的“容器” 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)
}

}

结果:

enter image description here

关于ios - 以编程方式创建部分屏幕 UIPageViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56399895/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com