问题
My homework project has a single RootVC with the top half of the page being a scrollable UIPageviewController object. The UIPageViewController has a sub-View Controller called SubVCOne.
Pressing a greeting button placed on SubVCOne presents a greeting View on the RootVC. I need too find a way to pass this information from the SubVCOne of the UIPageViewController to the RootVC w/o using protocols or delegates or caches; hence closures.
My attempts have been a little futile---
Root VC:
class RootVC: UIViewController {
let pagingContainer: UIView = {
let view = UIView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
view.addSubview(pagingContainer)
SubVCOne().closureComm = { [weak self] in
let greetingView = GreetingView()
self?.view.addSubview(greetingView)
}
pagingContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
pagingContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true
pagingContainer.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
pagingContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
addChild(pageController)
pageController.didMove(toParent: self)
pageController.view.translatesAutoresizingMaskIntoConstraints = false
pagingContainer.addSubview(pageController.view)
pageController.view.heightAnchor.constraint(equalTo: pagingContainer.heightAnchor, multiplier: 1).isActive = true
pageController.view.widthAnchor.constraint(equalTo: pagingContainer.widthAnchor, multiplier: 1).isActive = true
pageController.view.topAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true
pageController.view.bottomAnchor.constraint(equalTo: pagingContainer.bottomAnchor).isActive = true
pageController.view.leadingAnchor.constraint(equalTo: pagingContainer.leadingAnchor).isActive = true
pageController.view.trailingAnchor.constraint(equalTo: pagingContainer.trailingAnchor).isActive = true
}
}
The sub-ViewController of the UIPageVC:
class SubVCOne: UIViewController {
var closureComm: (() -> Void)?
let greetMeButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Greet!", for: .normal)
button.addTarget(self, action: #selector(acceptButtonPressed), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
@objc func acceptButtonPressed() {
print("Greet me button pressed")
let greetingView = GreetingView()
view.addSubview(greetingView)
closureComm?()
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemOrange
view.addSubview(greetMeButton)
greetMeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
greetMeButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
My UIPageViewController:
class PageViewController: UIPageViewController {
lazy var subViewControllers:[UIViewController] = {
return [SubVCOne()]
}()
init(transitionStyle style:
UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [String : Any]? = nil) {
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
setViewControllerFromIndex(index: 0)
}
func setViewControllerFromIndex(index:Int) {
self.setViewControllers([subViewControllers[index]], direction: UIPageViewController.NavigationDirection.forward, animated: true, completion: nil)
}
}
extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return subViewControllers.count
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
if currentIndex <= 0 {
return nil
}
return subViewControllers[currentIndex-1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
if currentIndex >= subViewControllers.count-1 {
return nil
}
return subViewControllers[currentIndex+1]
}
}
来源:https://stackoverflow.com/questions/59444564/why-wont-my-subvc-from-uipageviewcontroller-pass-data-to-my-view-controller-eff