gpt4 book ai didi

ios - 如何优化 UIPageViewController 以具有类似于 tableView.dequeueReusableCell(withIdentifier :for:)?) 的重用机制

转载 作者:行者123 更新时间:2023-11-28 19:26:12 25 4
gpt4 key购买 nike

到目前为止,我遇到的大多数 UIPageViewController 教程都会在滑动到所需页面时动态创建 UIViewController

未优化的 UIPageViewController 示例

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var contentView: UIView!

let dataSource = ["View Controller One", "View Controller Two", "View Controller Three", "View Controller Four"]

var currentViewControllerIndex = 0

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
configurePageViewController()
}

func configurePageViewController() {

guard let pageViewController = storyboard?.instantiateViewController(withIdentifier: String(describing: CustomPageViewController.self)) as? CustomPageViewController else {
return
}

pageViewController.delegate = self
pageViewController.dataSource = self

addChild(pageViewController)
pageViewController.didMove(toParent: self)

pageViewController.view.translatesAutoresizingMaskIntoConstraints = false

contentView.addSubview(pageViewController.view)

let views: [String: Any] = ["pageView": pageViewController.view]

contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[pageView]-0-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))

contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[pageView]-0-|", options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: views))

guard let startingViewController = detailViewControllerAt(index: currentViewControllerIndex) else {
return
}

pageViewController.setViewControllers([startingViewController], direction: .forward, animated: true)
}

func detailViewControllerAt(index: Int) -> DataViewController? {

if index >= dataSource.count || dataSource.count == 0 {
return nil
}

guard let detailViewController = storyboard?.instantiateViewController(withIdentifier: String(describing: DataViewController.self)) as? DataViewController else {
return nil
}

detailViewController.index = index
detailViewController.displayText = dataSource[index]

return detailViewController
}
}

extension ViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {

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

print ("presentationIndex \(currentViewControllerIndex)")

return currentViewControllerIndex
}

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

print ("presentationCount \(dataSource.count)")

return dataSource.count
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let dataViewController = viewController as? DataViewController

guard var currentIndex = dataViewController?.index else {
return nil
}

print ("viewControllerBefore \(currentIndex)")

if (currentIndex == 0) {
return nil
}

currentIndex -= 1

currentViewControllerIndex = currentIndex

return detailViewControllerAt(index: currentIndex)
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let dataViewController = viewController as? DataViewController

guard var currentIndex = dataViewController?.index else {
return nil
}

print ("viewControllerBefore \(currentIndex)")

if currentIndex == dataSource.count-1 {
return nil
}

currentIndex += 1

currentViewControllerIndex = currentIndex

return detailViewControllerAt(index: currentIndex)
}
}

但是,我几乎看不到任何关于如何优化 UIPageViewController 以处理大量页面的示例。

为每个页面重新创建新的 UIViewController 似乎不是最佳解决方案,因为它会很慢。它还占用了不必要的内存空间,因为大部分屏幕外的 UIViewController 是不可见的。

我们怎样才能拥有类似于 tableView.dequeueReusableCell(withIdentifier:for:) 的东西?

我们可以重新使用那些以前创建的、当前不可见的 UIViewController 吗?

非常感谢有关如何正确实现此功能的任何代码示例或教程资源。谢谢。

最佳答案

动态创建 Controller 可能会导致一些故障,所以我通常有一些像 var viewControllers: [UIViewController] 这样的数组来存储我的页面并实现 UIPageViewControllerDataSource

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let index = viewControllers.firstIndex(of: viewController), index > 0 else {
return nil
}

currentViewControllerIndex = index - 1
return viewControllers[currentViewControllerIndex]
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let index = viewControllers.firstIndex(of: viewController), index < viewControllers.count - 1 else {
return nil
}

currentViewControllerIndex = index + 1
return viewControllers[currentViewControllerIndex]
}

为了减少内存使用,您可以在页面更改时释放 View Controller 的 View :

    var currentViewControllerIndex = 0 {
didSet {
let range = currentViewControllerIndex - 1...currentViewControllerIndex + 1

for (offset, element) in viewControllers.enumerated() {
if range ~= offset {
element.loadViewIfNeeded()
} else {
element.view = nil
}
}
}
}

关于ios - 如何优化 UIPageViewController 以具有类似于 tableView.dequeueReusableCell(withIdentifier :for:)?) 的重用机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57175319/

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