Ios 在安装后设置视图控制器时,以编程方式添加的页面控件将消失 问题

Ios 在安装后设置视图控制器时,以编程方式添加的页面控件将消失 问题,ios,uipageviewcontroller,uipagecontrol,Ios,Uipageviewcontroller,Uipagecontrol,点击页面i上的跳过按钮(调用setViewControllers(uquo;:动画:),并将用户切换到页面视图控制器中的最后一页),然后再次滑回页面i,页面控件将消失 想要的结果 当页面视图控制器包含不同类型的视图控制器时,我希望以编程方式在页面视图控制器中的每个视图控制器的底部添加和显示自定义页面控件 迄今为止为解决这一问题所作的努力 每次出现页面控件时,将其添加到基本视图控制器 在包含缺少页面控件的视图控制器上调用loadView() 代码 我有一个walkthrootviewcontr

点击页面
i
上的跳过按钮(调用
setViewControllers(uquo;:动画:)
,并将用户切换到页面视图控制器中的最后一页),然后再次滑回页面
i
,页面控件将消失

想要的结果 当页面视图控制器包含不同类型的视图控制器时,我希望以编程方式在页面视图控制器中的每个视图控制器的底部添加和显示自定义页面控件

迄今为止为解决这一问题所作的努力
  • 每次出现页面控件时,将其添加到基本视图控制器
  • 在包含缺少页面控件的视图控制器上调用
    loadView()
代码 我有一个
walkthrootviewcontroller
,它包含一个
UIPageViewController
。页面视图控制器中的视图控制器的类型是两个子类
WalkthroughBaseViewController
,一种类型的第一个
n-1
,另一种类型的最后一个。我还没有包括最后一种类型的代码,因为就我所知,这是有效的

我在
演练bSaveViewController
中有此代码:

lazy var pageControl: UIPageControl = {
    let pageControl = UIPageControl(frame: .zero)
    pageControl.translatesAutoresizingMaskIntoConstraints = false
    pageControl.numberOfPages = numberOfPages
    pageControl.sizeToFit()
    pageControl.pageIndicatorTintColor = Colors.brown
    pageControl.currentPageIndicatorTintColor = Colors.silver
    pageControl.isUserInteractionEnabled = false
    pageControl.isEnabled = false
    return pageControl
}()
页面控件将添加到
viewDidLoad()
中的视图中:

如果用户在任何第一个
n-1
视图控制器上,用户可以点击“跳过”按钮向前跳到最后一个视图控制器。代码是

func skipWalkthrough() {
    guard let viewController = walkthroughPageViewControllerDataSource.viewController(at: lastIndex, storyboard: storyboard!) else { return }
    walkthroughPageViewController.setViewControllers([viewController], direction: .forward, animated: true)
}
参考文献 我强调了我认为很重要的代码,但这里是与应用程序演练相关的所有文件

walkthrootviewcontroller
演练bSaveViewController
演练HimageViewController
WalkthroughPageViewControllerDataSource

创建一个
ui页面控件
,将其放在演练的ootviewcontroller中,并在导航页面时进行更新-不要为每个子级创建页面控件


尽量不要使用
extension
s来覆盖方法-它可能会给您带来麻烦-请参阅。

这有点离题,但尽量不要使用
extension
s来覆盖方法-它可能会给您带来麻烦-请参阅,为什么要将
UIPageControl
放在每个子VC中?为什么不创建一个单独的控件,将其放入穿行视图控制器中,并在浏览页面时进行更新?这样做了!非常感谢你,@MilanNosáľ!感谢您提供有关扩展和重写方法的提示。请随意将其作为答案发布,我会将其标记为正确。也许我还不够清楚,但解决办法是:“为什么您要在每个子VC中放置UIPageControl?为什么不创建一个单独的控件,您可以将其放在演练RootViewController中,并在浏览页面时进行更新?”抱歉,我只是在玩CS:GO,而且是在匆忙中做的:D
func skipWalkthrough() {
    guard let viewController = walkthroughPageViewControllerDataSource.viewController(at: lastIndex, storyboard: storyboard!) else { return }
    walkthroughPageViewController.setViewControllers([viewController], direction: .forward, animated: true)
}
import UIKit

class WalkthroughRootViewController: UIViewController {

    // MARK: Regular Properties
    var walkthroughPageViewController: UIPageViewController!
    var walkthroughImages = [
        Images.w1,
        Images.w2
    ]
    var walkthroughStrings: [String] = [
        .localized(.walkthroughTitle1),
        .localized(.walkthroughZipCodeTitle)
    ]

    // MARK: Lazy Properties
    lazy var walkthroughPageViewControllerDataSource: WalkthroughPageViewControllerDataSource = {
        var dataSource = WalkthroughPageViewControllerDataSource()
        dataSource.walkthroughRootViewController = self
        return dataSource
    }()

    // MARK: Computed Properties
    var lastIndex: Int {
        return walkthroughImages.count - 1
    }
    var temporaryUserInput: String?
    var temporarySwitchPosition = false

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

// MARK: View Controller Life Cycle

extension WalkthroughRootViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Stop gray shadow from appearing under transition.
        navigationController?.view.backgroundColor = .white

        configurePageViewController()
    }
}

// MARK: Helper Methods

extension WalkthroughRootViewController {
    func configurePageViewController() {
        walkthroughPageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        walkthroughPageViewController.dataSource = walkthroughPageViewControllerDataSource
        walkthroughPageViewController.delegate = walkthroughPageViewControllerDataSource

        let startingViewController = storyboard!.instantiateViewController(withIdentifier: Strings.ViewControllerIdentifiers.walkthroughImage) as! WalkthroughImageViewController
        let startIndex = 0
        startingViewController.delegate = self
        startingViewController.pageIndex = startIndex
        startingViewController.text = walkthroughStrings[startIndex]
        startingViewController.image = walkthroughImages[startIndex]
        startingViewController.numberOfPages = walkthroughImages.count

        walkthroughPageViewController.setViewControllers([startingViewController], direction: .forward, animated: true)
        walkthroughPageViewController.view.frame = view.bounds
        add(walkthroughPageViewController)
    }
}

extension WalkthroughRootViewController: WalkthroughDelegate {
    func skipWalkthrough() {
        guard let viewController = walkthroughPageViewControllerDataSource.viewController(at: lastIndex, storyboard: storyboard!) else { return }
        walkthroughPageViewController.setViewControllers([viewController], direction: .forward, animated: true)
    }
}

extension WalkthroughRootViewController: WalkthrouZipCodeViewControllerDelegate {
    func walkththroughZipCodeViewController(_ viewController: WalkthroughZipCodeViewController, userEnteredText enteredText: String) {
        temporaryUserInput = enteredText
    }

    func walkthroughZipCodeViewController(_ viewController: WalkthroughZipCodeViewController, userChangedSwitchPosition position: Bool) {
        temporarySwitchPosition = position
    }
}
import UIKit

protocol WalkthroughDelegate: class {
    func skipWalkthrough()
}

class WalkthroughBaseViewController: UIViewController {
    // MARK: Regular Properties
    var pageIndex = 0
    var text = ""
    var delegate: WalkthroughDelegate?
    var numberOfPages = 0

    // Lazy Properties
    lazy var pageControl: UIPageControl = {
        let pageControl = UIPageControl(frame: .zero)
        pageControl.translatesAutoresizingMaskIntoConstraints = false
        pageControl.numberOfPages = numberOfPages
        pageControl.sizeToFit()
        pageControl.pageIndicatorTintColor = Colors.brown
        pageControl.currentPageIndicatorTintColor = Colors.silver
        pageControl.isUserInteractionEnabled = false
        pageControl.isEnabled = false
        return pageControl
    }()
}

// MARK: View Controller Life Cycle

extension WalkthroughBaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = Colors.silver

        view.addSubview(pageControl)
        NSLayoutConstraint.activate([
            pageControl.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            pageControl.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])

        view.accessibilityIdentifier = Strings.AccessibilityIdentifiers.walkthrough
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        pageControl.currentPage = pageIndex
    }
}
import UIKit

class WalkthroughImageViewController: WalkthroughBaseViewController {
    // MARK: @IBOutlets
    @IBOutlet weak var titleLabel: UILabel! {
        didSet {
            titleLabel.adjustsFontSizeToFitWidth = true
            titleLabel.textColor = Colors.silver
            titleLabel.numberOfLines = 0
        }
    }
    @IBOutlet weak var skipWalkthroughButton: UIButton! {
        didSet {
            skipWalkthroughButton.setTitleColor(Colors.silver, for: .normal)
            skipWalkthroughButton.titleLabel?.font = UIFont.preferredBoldFont(for: .body)
            skipWalkthroughButton.setTitle(.localized(.skip), for: .normal)
        }
    }
    @IBOutlet weak var imageView: UIImageView! {
        didSet {
            imageView.layer.shadowColor = Colors.brown.cgColor
            imageView.layer.shadowOffset = CGSize(width: 0, height: 1)
            imageView.layer.shadowOpacity = 1
            imageView.layer.shadowRadius = 1.0
            imageView.clipsToBounds = false
            imageView.contentMode = .scaleAspectFill
        }
    }

    // MARK: Regular Properties
    var image: UIImage?

    // MARK: View Controller Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.image = image
        titleLabel.text = text
    }
}

// MARK: @IBActions

extension WalkthroughImageViewController {
    @IBAction func skipWalkthrough(_ sender: UIButton) {
        delegate?.skipWalkthrough()
    }
}
import UIKit

class WalkthroughPageViewControllerDataSource: NSObject {
    // MARK: Regular Properties
    var walkthroughRootViewController: WalkthroughRootViewController!
}

extension WalkthroughPageViewControllerDataSource: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        var index = indexOfViewController(viewController as! WalkthroughBaseViewController)

        if index == NSNotFound || index == 0 {
            return nil
        }

        index -= 1

        return self.viewController(at: index, storyboard: walkthroughRootViewController.storyboard!)

    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        var index = indexOfViewController(viewController as! WalkthroughBaseViewController)

        if index == NSNotFound {
            return nil
        }

        index += 1

        if index == walkthroughRootViewController.walkthroughImages.count {
            return nil
        }

        return self.viewController(at: index, storyboard: walkthroughRootViewController.storyboard!)
    }
}

extension WalkthroughPageViewControllerDataSource {
    func viewController(at index: Int, storyboard: UIStoryboard) -> WalkthroughBaseViewController? {
        if walkthroughRootViewController.walkthroughImages.count == 0 || index >= walkthroughRootViewController.walkthroughImages.count {
            return nil
        }

        var viewController: WalkthroughBaseViewController?

        if index == walkthroughRootViewController.lastIndex {
            viewController = storyboard.instantiateViewController(withIdentifier: Strings.ViewControllerIdentifiers.walkthroughZipCode) as? WalkthroughZipCodeViewController
            if let viewController = viewController as? WalkthroughZipCodeViewController {
                viewController.pageIndex = index
                viewController.walkthroughZipCodeDelegate = walkthroughRootViewController
                viewController.temporaryUserInput = walkthroughRootViewController.temporaryUserInput
                viewController.temporarySwitchPosition = walkthroughRootViewController.temporarySwitchPosition
                viewController.numberOfPages = walkthroughRootViewController.walkthroughImages.count
                viewController.image = walkthroughRootViewController.walkthroughImages[index]
            }
        } else {
            viewController = storyboard.instantiateViewController(withIdentifier: Strings.ViewControllerIdentifiers.walkthroughImage) as? WalkthroughImageViewController
            if let viewController = viewController as? WalkthroughImageViewController {
                viewController.delegate = walkthroughRootViewController
                viewController.pageIndex = index
                viewController.image = walkthroughRootViewController.walkthroughImages[index]
                viewController.text = walkthroughRootViewController.walkthroughStrings[index]
            }
        }

        return viewController
    }

    func indexOfViewController(_ viewController: WalkthroughBaseViewController) -> Int {
        return viewController.pageIndex
    }
}

extension WalkthroughPageViewControllerDataSource: UIPageViewControllerDelegate {
}