我希望该开关控制用户的跟踪记录,但是我的开关位于secondView上。是否有必要发送通知或使用协议委托?
firstView
class MapViewController: UIViewController {
@IBOutlet weak var mainMapView: MKMapView!
func drawRoute(locationArray: [CLLocation]) {
if locationArray.count > 1 {
let destinationLocIndex = (locationArray.count) - 1
let startLocIndex = (locationArray.count) - 2
let destinationloc = locationArray[destinationLocIndex].coordinate
let startLoc = locationArray[startLocIndex].coordinate
let routeArray = [startLoc, destinationloc]
let geodesicLine = MKGeodesicPolyline(coordinates: routeArray, count: routeArray.count)
mainMapView.add(geodesicLine, level: .aboveRoads)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// show current user's location
setLocation(nowlocation: locations.last!)
//I want to control it from the switch on the second page
drawRoute(locationArray: userLocation)
}
}
seconView
class SencodTableViewController: UITableViewController {
@IBAction func drawRouteSwitch(_ sender: UISwitch) {
if sender.isOn == true {
} else {
}
}
我想从第二个页面开关控制drawRoute功能,该怎么办?
答案 0 :(得分:0)
您确实有两个选择,例如NSNotification
,委派甚至是单例(在这种情况下不建议使用)。我最喜欢的在一对特定视图控制器之间传递信息的方法是通过委派。这很简单。无需通过系统的通知中心。这很具体:只有一个侦听器和一个通知器。
创建以下委托:
class SencodTableViewControllerDelegate: class {
func switchValueDidChange(_ viewController: SencodTableViewController, isSwitchOn: Bool);
}
您通过prepare(for:)
方法将第一个VC设置为“监听器”。
let SegueToSecondViewID = "segueToSecondViewID"
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == SegueToSecondViewID {
if let secondVC = segue.destination as? SencodTableViewController {
secondVC.delegate = self
}
} else {
super.prepare(for: segue, sender: sender)
}
}
您还应该确保在情节提要中也定义SegueToSecondViewID
。转到情节提要,单击segue(VC之间的链接节点),然后更新下图所示的字段:
在您的第一个VC中,还应遵循SencodTableViewControllerDelegate
协议来实现“响应”方法:
extension MapViewController: SencodTableViewControllerDelegate {
func switchValueDidChange(_ viewController: SencodTableViewController, isSwitchOn: Bool) {
// Do what you want with drawRoute
}
}
然后,当您要发送开机消息时:
class SencodTableViewController: UITableViewController {
weak var delegate: SencodTableViewControllerDelegate?
...
@IBAction func drawRouteSwitch(_ sender: UISwitch) {
delegate.switchValueDidChange(self, sender.isOn)
}
}
答案 1 :(得分:0)
您将需要使用协议委托。
首先定义一个委托(它可以具有任意数量的功能)
protocol SwitchToggleDelegate{
func didToggleSwitch(state: Bool)
}
在第二个视图(带有开关)中: 引用委托(以调用所需的方法)
var switchDelegate: SwitchToggleDelegate? = nil
并从您的开关操作中调用委托方法:(我已经包括了完整的代码)
class View2: UIViewController {
var switchDelegate: SwitchToggleDelegate? = nil
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func OnSwitchToggled(_ sender: UISwitch) {
switchDelegate?.didToggleSwitch(state: sender.isOn)
}
}
在您的第一个视图中:
订阅新的代表并添加所需的方法:
class View1: UIViewController, SwitchToggleDelegate { }
func didToggleSwitch(state: Bool){
//Do Something
labelOne.text = "Switch is \(state)"
}
您还需要将第一个视图的委托设置为等于第二个视图。由于我为此使用了容器视图,因此我正在使用segue做准备:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "embedded"{
let view2: View2 = segue.destination as! View2
view2.switchDelegate = self
}
}
现在,当切换开关时,将调用委托方法func didToggleSwitch(state: Bool)
,并且预订该委托方法的任何内容(例如您的第一个视图)都将听到此委托回调,并执行为委托准备的任何代码。