Swift-在协议/委托之间传递数据时出错(发现为零)
我正在用swift 3.0开发一个应用程序。我想做的是,从“MainMapVC”类,这是一个视图,其中有一个带有日期滑块的地图(请参见附件)。我想移动滑块并将滑块位置(1、2或3)发送到LeftSideViewController,它是根据所选日期更新内容的侧视图(图例) MainMapVC的视图:Swift-在协议/委托之间传递数据时出错(发现为零),swift,null,delegates,protocols,Swift,Null,Delegates,Protocols,我正在用swift 3.0开发一个应用程序。我想做的是,从“MainMapVC”类,这是一个视图,其中有一个带有日期滑块的地图(请参见附件)。我想移动滑块并将滑块位置(1、2或3)发送到LeftSideViewController,它是根据所选日期更新内容的侧视图(图例) MainMapVC的视图: import UIKit protocol MainMapVCDelegate: class { func moveSliderDates(datePos: Int) } clas
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))
}
}
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()
}
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)
}
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)
}
带有图例的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))
}
}
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()
}
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)
}
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)
}
现在我必须在两个视图控制器之间传递一个值。但问题是,我得到了错误“致命错误:在展开可选值时意外发现nil”。基本上我有一个“零”代表
weak var delegate: LeftSideDelegate? = nil
但是,请不要找到错误所在,因为委托的定义类似于“var delegate:mainmapvcdegate!”,我在“MainMapVC”类中将其称为“delegate.moveSliderDates(datePos:Int(roundedValue))”
有人知道我在代表发言中失败的地方吗?谢谢:)
我附加了这两个类的代码,以便您看到整个代码
Class 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))
}
}
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()
}
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)
}
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)
}
moveSliderDates函数中的委托值为“nil”:
delegate?.moveSliderDates(datePos: Int(roundedValue))
类LeftSideViewController(第一种方式):
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))
}
}
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()
}
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)
}
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)
}
由于“MainVC”的委托为“nil”,因此不能进入此函数内部:
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))
}
}
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()
}
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)
}
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)
}
Class 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))
}
}
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()
}
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)
}
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)
}
类LeftSideViewController(第二种方式):
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))
}
}
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()
}
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)
}
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)
}
从不进入函数列表功能您会收到错误,因为您通过以下代码将委托定义为强制展开noy nil版本
var delegate:LeftSideDelegate代码>
相反,你需要像这样改变它。您不应该为代理创建强引用循环
weak var delegate: LeftSideDelegate? = nil
然后,对所有委托调用执行包装版本委托调用
delegate?.changeZindexDelivery()
除此之外,将行protocolleftsidedelegate{
更改为protocolleftsidedelegate:class{
使用委托在视图控制器之间传递数据
首先,在要将数据传递给另一个视图控制器的类中,以这种方式声明协议
protocol SampleDelegate: class {
func delegateFunctionCall(data: String)
}
然后,使用弱变量类型将委托变量创建为可选变量。若要传递数据或触发操作,请使用调用委托方法
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)
@JordiGallenRenau您正在分机中接收此协议调用,对吗?(extension MainMapVC:LeftSideDelegate
)在里面放一个断点,看看它是否被调用。顺便说一句,你说你不能调用moveSliderDates函数是什么意思?这会给你带来一些错误?@jordigallenreneu哦,所以你需要为你的主视图控制器准备一个segue方法。目标必须是你的左视图控制器。然后你需要执行destinationViewController.delegate=self@JordiGallenRenau您仍然无法使其工作吗?您没有使用segue吗?您希望从main到left传递数据,因此您需要的是,在您的left view控制器上定义协议,创建委托变量并对其调用方法。然后在您的maincontroller上,将main本身设置为left view控制器的委托对象呃,我被你的观点弄糊涂了code@JordiGallenRenau我已经更新了两种在视图控制器之间传递数据的正常方式。如果这有帮助,请将其标记为正确答案。如果仍然不正确,请告诉我work@JordiGallenRenau当目标视图控制器运行时,是否尝试调用委托方法尚未初始化?这两种方法仅在源视图控制器和目标视图控制器有效时才起作用