Как передать значение selectedsegmentindex другому viewcontroller?

У меня есть PopUpViewController, который появляется при нажатии кнопки в основном ViewController. У меня есть speedDisplay (UILabel) на трех разных ViewController, которые я хочу иметь возможность переключать вывод между MPH и KMH, и я не могу понять, как это сделать. У меня есть segmentControl в PopUpViewController, который я пытаюсь реализовать, чтобы это произошло. Может кто-нибудь помочь мне здесь?

import UIKit

public enum Speed {
case KMH
case MPH
}
protocol PopUpViewControllerDelegate: class {

func selectedSpeedType(_ type: Speed)
}

class PopUpViewController: UIViewController, UIGestureRecognizerDelegate {

weak var delegate: PopUpViewControllerDelegate?


@IBOutlet weak var altitudeSegment: UISegmentedControl!
@IBOutlet weak var tempSegment: UISegmentedControl!
@IBOutlet weak var speedSC: UISegmentedControl!

@IBOutlet weak var doneButton: UIButton!
@IBOutlet weak var settingsView: UIView!



override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)

    settingsView.layer.masksToBounds = true
    settingsView.layer.cornerRadius = 8

    doneButton.layer.masksToBounds = true
    doneButton.layer.cornerRadius = 8

    let items = ["MPH", "KMH"]
    let segmentedControl = UISegmentedControl.init(items: items)
    segmentedControl.selectedSegmentIndex = 0        
    segmentedControl.addTarget(self, action: #selector(speedChoice(_sender:)), for: UIControl.Event.valueChanged)
    self.view.addSubview(segmentedControl)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func speedChoice(_ sender: UISegmentedControl) {

    let index = sender.selectedSegmentIndex

    switch index {
    case 0:
        // Needs to euqal MPH to use on speedDisplay in another viewController
    case 1:
        // Needs to euqal KMH to use on speedDisplay in another viewController
    default:
        break
    }
}

Вот функция, которую я использую для ViewController для скорости:

override func viewDidLoad() {
    super.viewDidLoad()
    getCurrentDateTime()
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
        locationManager.headingFilter = 5
    }
     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    map.mapType = MKMapType.standard
    let location = locations[0]
    let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
    let region = MKCoordinateRegion(center: myLocation, span: span)
    map.setRegion(region, animated: true)
    self.map.showsUserLocation = true

    let speed = location.speed
    if speed < 2 {
        self.speedDisplay.text = "0.0"
    }
    else {
        if speedType == .MPH {
            self.speedDisplay.text = String(format: "%.1f", speed * 2.236936284, "MPH")
            speedTypeLabel.text = "MPH"
        }
        else {
            self.speedDisplay.text = String(format: "%.1f", speed * 3.6, "KMH")
            speedTypeLabel.text = "KMH"
        }
    }
extension ViewController: PopUpViewControllerDelegate {
    func selectedSpeedType(_ type: Speed) {
        speedType = type
    }
}

И код для PopUp:

@IBAction func showPopup(_ sender: Any) {

    let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
    self.addChild(popOverVC)
    popOverVC.view.frame = self.view.frame
    self.view.addSubview(popOverVC.view)
    popOverVC.didMove(toParent: self)

    }

}

У меня есть следующее для сохранения segmentedController: Я считаю, что мне что-то не хватает, потому что каждый раз, когда я выбираю сегмент, он возвращается к сегменту 0. Он распечатывается так, как будто он работает, но не сохраняет выбор. Любые идеи?

@IBAction func closePopUp(_ sender: UIButton) {
    self.view.removeFromSuperview()
    }

Как вы показываете PopUpViewController из ViewController? Поделитесь кодом пожалуйста

Sateesh Yemireddi 26.10.2018 07:17

Я добавил это в код выше. Он появляется, когда я нажимаю кнопку, расположенную на первом ViewController приложения. У меня есть всего три представления, плюс всплывающее окно.

B. Deaton 26.10.2018 11:20

Я имею в виду, поделитесь кодом контроллера представления, в котором вы представляете PopUpViewController

Sateesh Yemireddi 26.10.2018 11:22

Не связано, но никогда не используйте (sender as AnyObject).state, если тип отправителя известен и статичен. Используйте func onClkPanGesture(_ sender: UIGestureRecognizer), а затем просто sender.state == .began, в данном случае даже лучше инструкцию switch.

vadian 26.10.2018 11:31

прости за это. Я понял, что дважды опубликовал этот код.

B. Deaton 26.10.2018 12:18
1
5
181
1

Ответы 1

Используйте механизм delegate для отправки данных от одного ViewController к другому.

Внутри PopUpViewController

import UIKit

public enum Speed {
    case KMPH
    case MPH
}
protocol PopUpViewControllerDelegate: class {

    func selectedSpeedType(_ type: Speed)
}

class PopUpViewController: UIViewController, UIGestureRecognizerDelegate {

    weak var delegate: PopUpViewControllerDelegate?

    //This is global variable (internal protection level) and can be get/set from outside of the class.
    var speedType = Speed.KMPH //New line

    @IBOutlet weak var altitudeSegment: UISegmentedControl!

    ......
    ......

    override func viewDidLoad() {
        super.viewDidLoad()

        .......

        //We can select the segment control with corresponding value even popover is removed from the ViewController.
        altitudeSegment.selectedSegmentIndex = speedType.hashValue //New line
    }

    @IBAction func speedChoice(_ sender: Any) {

        let segmentControl = sender as! UISegmentedControl
        if segmentControl.selectedSegmentIndex == 0 {
            delegate?.selectedSpeedType(.KMPH)
        } else {
            delegate?.selectedSpeedType(.MPH)
        }
    }
}

Внутри YourViewController:

class ViewController: UIViewController {

    var speedType: Speed! = .KMPH
    var popOverVC: PopUpViewController!

    override func viewDidLoad() {
        super.viewDidLoad()

        popVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
        popVC.delegate = self
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        .....

        self.speedDisplay.text = "\(String(format: "%.1f", speed * 2.236936284)) \((speedType == .KMPH) ? "KMPH" : "MPH")"
    }

    @IBAction func showPopup(_ sender: Any) {

        self.addChild(popOverVC)
        popOverVC.view.frame = self.view.frame
        //Assign the speedType to selected value back in PopOverViewController, and update the segmentControl to new value.
        popOverVC.speedType = speedType //New line
        self.view.addSubview(popOverVC.view)
        popOverVC.didMove(toParent: self)
    }
}

extension ViewController: PopUpViewControllerDelegate {

    func selectedSpeedType(_ type: Speed) {

        speedType = type
    }
}

Выглядит хорошо. Я получаю три ошибки в строке speedDisplay.text. Ошибка 1 - невозможно присвоить значение: бинарный оператор возвращает неизменяемое значение, Ошибка 2 - Ожидаемое значение »,« Вставка разделителя »и Ошибка 3 - Ожидаемое выражение в списке выражений.

B. Deaton 26.10.2018 13:14

Прости за это. Обновил ответ, проверьте еще раз. Неправильно указанная скорость и тернарный оператор. скорость изменено speedType

Sateesh Yemireddi 26.10.2018 13:21

Я все еще получаю одну ошибку в строке speedDisplay - тип выражения "Bool" неоднозначен без дополнительного контекста. Я думаю, мне нужно различать MPH и KMPH в метрах в секунду.

B. Deaton 26.10.2018 13:35

Проверьте ответ сейчас

Sateesh Yemireddi 26.10.2018 13:45

Спасибо за помощь Сатиш. Я должен поработать над этим позже. Но вы определенно направили меня в правильном направлении.

B. Deaton 26.10.2018 13:58

Сатиш - Думаю, я довольно близок к тому, чтобы завершить это, но у меня проблема с сегментным контроллером, сохраняющим то, что я выбрал.

B. Deaton 30.10.2018 23:46

IVar speedType в ViewController всегда сохраняет значение, выбранное altitudeSegmentControl. Так есть ли что-то для нас экономить?

Sateesh Yemireddi 31.10.2018 04:09

Когда я выбираю случай 1 в сегменте управления, он автоматически возвращается к случаю 0?

B. Deaton 31.10.2018 20:18

Привет, @ B.Deaton, извините за поздний ответ. На самом деле, я видел ваше сообщение утром (по Индии, время по Гринвичу +5.30). Я обновил код, комментируя строки тегом «Новая строка». Пожалуйста, посмотрите ... !!! Если вы практикуетесь в iOS, было бы лучше иметь репозиторий GitHub, чтобы мы могли безупречно запускать ваш код на наших машинах.

Sateesh Yemireddi 01.11.2018 17:29

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

B. Deaton 20.11.2018 23:23

Другие вопросы по теме