У меня есть UISwitch на secondView, как мне управлять методом переключения - PullRequest
0 голосов
/ 26 июня 2018

Я хочу, чтобы коммутатор управлял записью трека пользователя, но мой коммутатор находится во втором окне. Нужно ли отправлять уведомления или использовать протокол делегата?

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 голосов
/ 26 июня 2018

Вам нужно будет использовать делегата протокола.

Начните с определения делегата (это может иметь любое количество функций)

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)"
    }

Вам также нужно будет установить делегата первого представления равным второму. Так как для этого я использую контейнерное представление, я использую подготовку для перехода:

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), и все, что подписано на этот метод делегата (например, ваш первый просмотр), будет прослушивать этот обратный вызов делегата и выполнять любой код, который вы подготовили для делегата.

0 голосов
/ 26 июня 2018

У вас действительно есть пара опций, таких как NSNotification, делегирование или даже синглтон (не рекомендуется для этого сценария). Мой любимый способ передачи информации между определенной парой контроллеров представления, подобный этому, - делегирование. Это просто. Не нужно проходить через центр уведомлений системы. И это конкретно: только один слушатель и один уведомитель.

Создайте следующий делегат:

class SencodTableViewControllerDelegate: class {
    func switchValueDidChange(_ viewController: SencodTableViewController, isSwitchOn: Bool);
}

Вы настроили первый VC в качестве «слушателя» в методе prepare(for:).

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

В вашем первом 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)
    }

}
...