我在secondView上有一个UISwitch,如何控制switch方法

时间:2018-06-26 12:28:51

标签: ios swift uiswitch

我希望该开关控制用户的跟踪记录,但是我的开关位于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功能,该怎么办?

2 个答案:

答案 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之间的链接节点),然后更新下图所示的字段:

Segue ID update

在您的第一个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),并且预订该委托方法的任何内容(例如您的第一个视图)都将听到此委托回调,并执行为委托准备的任何代码。