我知道这个问题已被问了很多次。但这里的情况发生了变化。我正在使用MMParallaxView,看起来非常棒。
但是现在,我想在这两个View控制器之间进行通信。让我告诉你,这个github代码可以帮助我们创建像ios Map App这样的视图。我的意思是你可以拥有Map(作为第一个视图控制器),你可以在第一个视图控制器的顶部有一个视图控制器列表。就像地图应用程序一样。
现在我想点击UITableView单元格并想要在地图上导航。为此,我知道如何捕获委托方法。我在UItableView单元上成功获得了点击。但是如何将点击的项目数据发送到1stView Controller,以便它可以在地图上显示或标记选定的区域。
我知道这也可以做到。但是怎么样?
修改MMParallaxView的示例应用程序...
在ChildBottomViewController.swift
在顶部(课堂外)添加:
protocol CellTapDelegate {
func didSelectRow(indexPath: IndexPath)
}
在课程开头添加此行:
var cellTapDelegate: CellTapDelegate?
将didSelectRowAt
函数更改为:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.async { [weak self] in
self?.cellTapDelegate?.didSelectRow(indexPath: indexPath)
}
}
在MapViewController.swift
将类声明更改为:
class MapViewController: UIViewController, CellTapDelegate {
并添加此功能:
@objc func didSelectRow(indexPath: IndexPath) {
print("Delegate got didSelectRow for: \(indexPath)")
}
然后,在SecondViewController.swift
在viewDidLoad()
的末尾添加:
var mapVC: MapViewController?
var bottomVC: ChildBottomViewController?
for vc in self.childViewControllers {
if vc is MapViewController {
mapVC = vc as? MapViewController
} else if vc is ChildBottomViewController {
bottomVC = vc as? ChildBottomViewController
}
}
// if we found valid child view controllers, set the delegate
if mapVC != nil && bottomVC != nil {
bottomVC?.cellTapDelegate = mapVC
}
现在,从“从下向上滑动”表视图中选择一行将选定的indexPath发送到其委托 - 地图视图控制器。
protocol CellTapDelegate {
func didTapOnItem(obj: MyObject)
}
class MyViewControllerContainingTheTableView : UIViewcontroller {
weak var delegate: CellTapDelegate?
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
let item = arrayOfObjects[indexpath.row]
self.delegate.didTapOnItem(item)
}
}
//View Controller where you you will have the listner
class FirstViewController : UIViewController {
func setupParalax() {
// you have to modify this according to your need
let vc = MyViewControllerContainingTheTableView()
vc.delegate = self
}
}
extension FirstViewController: CellTapDelegate {
func didTapOnItem(obj: MyObject) {
// you have your required object here
}
}
这应该可以通过实现自己的委托来实现,但我对MMParrallaxView的了解是,只有一个视图控制器显示两个视图,这意味着视图控制器应该能够在两个视图之间传递信息。在这种情况下,视图控制器将实现表视图委托方法,并将表视图添加到底视图。然后将地图添加到顶视图。这应该允许您捕获表视图单元格选择并相应地更新顶视图中的地图。
基于我认为您正在使用的结构的示例:
public class FirstViewController {
public let parallaxView = MMParallaxView()
private var secondViewController: SecondViewController
private var thirdViewController: ThirdViewController
override open func viewDidLoad() {
secondViewController = SecondViewController()
thirdViewController = ThirdViewController()
super.viewDidLoad()
self.view.addSubview(parallaxView)
thirdViewController.delegate = secondViewController
parallaxView.parallaxTopView = secondViewController.view
self.addChildViewController(secondViewController)
secondViewController.didMove(toParentViewController: self)
parallaxView.parallaxBottomView = thirdViewController.view
self.addChildViewController(thirdViewController)
thirdViewController.didMove(toParentViewController: self)
}
}
public class SecondViewController: ThirdViewControllerDelegate {
public func updateMap() {
// Update map
}
}
public class ThirdViewController: UITableViewDelegate {
weak var delegate ThirdViewControllerDelegate?
private var table: UITableView = UITableView()
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.updateMap()
}
}
protocol ThirdViewControllerDelegate: class {
public func updateMap() {}
}
如果视图控制器通过Storyboard实例化,那么你可以试试这个:
public class MasterViewController {
var secondViewController: SecondViewController?
override func viewDidLoad() {
super.viewDidLoad()
self.performSegue(withIdentifier: "MMParallaxTop", sender: nil)
self.performSegue(withIdentifier: "MMParallaxBottom", sender: nil)
}
override open func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let secondVC = segue.destination as? SecondViewController {
secondViewController = secondVC
}
if let thirdVC = segue.destination as? ThirdViewController, let second = secondViewController {
thirdVC.delegate = second
}
}
}