我已经在网上搜索了几个小时,现在认为这将是一件容易的事,但事情并没有按计划进行。这个问题经过编辑,一些伟大的家伙给出了很好的答案,但我仍然在苦苦挣扎。
这是一个场景,我有一个始终可见的 viewControllerA 。此视图顶部有一个小按钮,当我点击它时, viewControllerB 作为静态 tableViewController 。它是一个从左到右的幻灯片视图,说实话就像其他应用程序一样。
tableView中有一个部分和几个行,当我点击第四行时,我出现 viewControllerC ,那里有一个 UISwitch 按钮。当我关闭 viewControllerC 时,再次出现 viewControllerA 。 viewControllerB 是我的菜单控制器,因此它不是我更关心的问题。现在我想将数据从 viewControllerC 传递到 viewControllerA 。这是我破碎的代码:
viewControllerC :
class viewControllerC: UIViewController {
..//
@IBAction func switchTapped(_ sender: UISwitch) {
let vc = viewControllerA()
if sender.isOn == true {
vc.state = true
} else if sender.isOn == false {
vc.state = false
}
}
..//
}
viewControllerA :
class viewControllerA: UIViewController, GMSMapViewDelegate {
var state:Bool?
...//
if self.state == true {
self.mapView.isTrafficEnabled = true
} else {
self.mapView.isTrafficEnabled = false
}
}
但它不起作用我知道我没有朝着正确的方向前进。从示例中我可以看到,当 UISwitch 时 ture , false > off 从 viewControllerC 到 viewControllerA 。有些人提出了委托方法,但我仍在努力。我正在关注此link,我认为“通过应用程序的共享状态向后传递数据”部分符合我的标准。虽然我需要帮助。提前谢谢。
答案 0 :(得分:4)
您可以使用Delegate模式传递数据,这是一个想法:
WHERE date d
BETWEEN '2017-01-01' -- just a sample fixed date
AND DATEADD(D, CONTACT_DATE, -1) -- to show a day before Contact Date
答案 1 :(得分:1)
首先,当你启动viewControllerA:
时让vc = viewControllerA()
您正在创建一个新的viewcontrol实例,它不会引用您的第一个视图控件。
您可以通过不同方式将数据传递给viewcontrollers。 您可以使用delage模式,也可以使用展开。
在委托方法中,首先定义一个类类型协议,其中包含一个函数定义,用于在viewControllerA中更改内容。
protocol ViewControllerBDelegate: class {
func changeSwitch(toValue: Boolean)
}
然后在ViewControllerB中定义对委托
的弱引用weak var delegate: ViewControllerBDelegate?
然后在ViewControlA上采用此协议:
extension ViewControllerA: ViewControllerBDelegate {
func changeSwitch(toValue: Boolean) {
state = toValue
}
}
当您想要呈现或推送到ViewControllerB时,您应该将此变量设置为self
let vc = ViewControllerB()
vc.delegate = self
present(vc, animated: true, completion: nil)
// or navigationController. pushViewController(vc, animated: true)
如果你使用segue从一个viewcontroller导航到另一个viewcontroller,你应该在prepare中设置委托变量(对于segue,sender)。在ViewControllerA中重写此函数
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" ,
let vc = segue.destination as? ViewControllerB {
vc.delegate = self
}
}
然后,当切换值更改时,您可以使用委托更改ViewControllerA中的值
delegate?.changeSwitch(toValue: sender.isOn)
on wind允许您将子视图控制器弹出或关闭到某个父级,然后执行某些操作。您可以阅读完整的教程here
修改强>
对于链委托,您可以将委托传递给ViewController B,然后将相同的委托传递给ViewController C.
在视图控制器C中定义相同类型的委托
weak var delegate: ViewControllerBDelegate?
然后在导航到查看控制器c的视图控制器B中传递相同的委托
let vc = ViewControllerC()
vc.delegate = self.delegate
present(vc, animated: true, completion: nil)
编辑2
SWRevealViewController是不同的场景。 revealController有一个名为frontViewController的属性。如果你不推动任何其他控制器显示,它可以是你的ViewControllerA。使用frontViewController处理它是很棘手的,你应该确定frontController是否是ViewControllerA。
所以我建议你使用另一种方法与ViewControllerA进行通信。你可以使用NotificationCenter。
extension Notification.Name {
static let updateMap = Notification.Name("updateMap")
}
ViewControllerA中的
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(updateMap(_:)), name: .updateMap, object: nil )
}
@objc func updateMap(notification: NSNotification) {
if let state = notification.userInfo?["state"] as? Bool {
// do something with state
}
}
并在ViewControllerC中,当切换值为Changed时发布通知:
let userInfoDic:[String: Bool] = ["state": sender.isOn]
// post a notification
NotificationCenter.default.post(name: .updateMap, object: nil, userInfo: userInfoDic)
如果再次推送显示中的frontViewController。透露将启动 用于frontViewController的新ViewControllerA。在这种情况下你有 在UserDefault中设置设置,在ViewControllerA中读取此内容 设置。
使用UserDefaults:
ViewControllerC中的
UserDefaults.standard.setValue(sender.isOn, forKey: "mapState")
ViewControllerA中的
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let state = UserDefaults.standard.value(forKey: "mapState") ?? false
self.mapView.isTrafficEnabled = state
}