我正在使用swift 3.0开发一个应用程序。我想要做的是,来自" MainMapVC" class,这是一个带有日期滑块的地图的视图(参见附图)。我想移动滑块并将滑块位置(1,2或3)发送到LeftSideViewController,这是侧视图(图例),根据所选日期更新内容。
MainMapVC视图:
使用图例的MainMapVC视图:
好吧,我已经到了必须在两个视图控制器之间传递值的地步。但问题是我得到了错误"致命错误:在展开可选值"时意外地发现了nil。基本上我有一个" nil"委派。
但是找不到错误的位置,因为委托的定义就像" var delegate:MainMapVCDelegate!"我称之为" delegate.moveSliderDates(datePos:Int(roundedValue))"在" MainMapVC"类。
是否有人知道代表声明中我失败的地方?谢谢:)
我附上两个类的代码,以便您看到整个代码。
类MainMapVC(第一种方式):
import UIKit
protocol MainMapVCDelegate: class {
func moveSliderDates(datePos: Int)
}
class MainMapVC: UIViewController, UISearchBarDelegate, CLLocationManagerDelegate, GMSMapViewDelegate {
//MARK: VARIABLES
weak var delegate: MainMapVCDelegate? = nil
let step: Float = 1
@IBAction func moveSliderDates(_ sender: UISlider) {
let roundedValue = round(sender.value / step) * step
sender.value = roundedValue
delegate?.moveSliderDates(datePos: Int(roundedValue))
}
}
moveSliderDates函数中的委托值为" nil":
delegate?.moveSliderDates(datePos: Int(roundedValue))
类LeftSideViewController(第一种方式):
import UIKit
class LeftSideViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, customCellDelegate, MainMapVCDelegate {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MainMapVC" {
let secondViewController = segue.destination as! MainMapVC
secondViewController.delegate = self
}
}
func moveSliderDates(datePos: Int){
print(datePos)
print("/////////////")
tableSideLeft.reloadData()
}
不能进入此功能,因为" MainVC"的代表是" nil":
类MainMapVC(第二种方式):
let step: Float = 1
@IBAction func moveSliderDates(_ sender: UISlider) {
let roundedValue = round(sender.value / step) * step
sender.value = roundedValue
let data:[String: Int] = ["data": Int(roundedValue)]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data)
}
类LeftSideViewController(第二种方式):
func listnerFunction(_ notification: NSNotification) {
if let data = notification.userInfo?["data"] as? String {
print(data)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
}
永远不会进入功能listnerFunction
答案 0 :(得分:2)
您收到错误是因为您通过此代码var delegate: LeftSideDelegate!
相反,你需要像这样改变它。您不应该为委托创建强大的参考周期。
weak var delegate: LeftSideDelegate? = nil
然后,对于所有委托的calles,执行包装版本委托调用
delegate?.changeZindexDelivery()
除此之外,请将您的专线protocol LeftSideDelegate {
更改为protocol LeftSideDelegate : class {
使用委托
在视图控制器之间传递数据首先,在要将数据传递给另一个视图控制器的类中,以这种方式声明协议
protocol SampleDelegate: class {
func delegateFunctionCall(data: String)
}
然后,使用类型weak var创建委托变量作为可选项。调用委托方法,您想要传递数据或触发操作
class SecondViewController: UIViewController {
weak var delegate: SampleDelegate? = nil
@IBAction func sendTextBackButton(sender: AnyObject) {
delegate?.delegateFunctionCall(data: textField.text!)
}
}
最后,在您希望接收操作或数据的视图控制器中,实现协议。当您启动第二个视图控制器时,将其委托变量设置为当前视图控制器
class FirstViewController: UIViewController, SampleDelegate {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSecondViewController" {
let secondViewController = segue.destination as! SecondViewController
secondViewController.delegate = self
}
}
func delegateFunctionCall(data: String) {
label.text = data
}
}
使用通知
在视图控制器之间传递数据在目标视图控制器中,注册准备调用的处理函数。您可以在视图中添加此注册码 然后在另一个视图控制器中,如果要传递数据,只需调用此NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
func listnerFunction(_ notification: NSNotification) {
if let data = notification.userInfo?["data"] as? String {
// do something with your data
}
}
let data:[String: String] = ["data": "YourData"]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data)