У меня есть 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()
}
Я добавил это в код выше. Он появляется, когда я нажимаю кнопку, расположенную на первом ViewController приложения. У меня есть всего три представления, плюс всплывающее окно.
Я имею в виду, поделитесь кодом контроллера представления, в котором вы представляете PopUpViewController
Не связано, но никогда не используйте (sender as AnyObject).state
, если тип отправителя известен и статичен. Используйте func onClkPanGesture(_ sender: UIGestureRecognizer)
, а затем просто sender.state == .began
, в данном случае даже лучше инструкцию switch
.
прости за это. Я понял, что дважды опубликовал этот код.
Используйте механизм 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 - Ожидаемое выражение в списке выражений.
Прости за это. Обновил ответ, проверьте еще раз. Неправильно указанная скорость и тернарный оператор. скорость изменено speedType
Я все еще получаю одну ошибку в строке speedDisplay - тип выражения "Bool" неоднозначен без дополнительного контекста. Я думаю, мне нужно различать MPH и KMPH в метрах в секунду.
Проверьте ответ сейчас
Спасибо за помощь Сатиш. Я должен поработать над этим позже. Но вы определенно направили меня в правильном направлении.
Сатиш - Думаю, я довольно близок к тому, чтобы завершить это, но у меня проблема с сегментным контроллером, сохраняющим то, что я выбрал.
IVar speedType в ViewController всегда сохраняет значение, выбранное altitudeSegmentControl. Так есть ли что-то для нас экономить?
Когда я выбираю случай 1 в сегменте управления, он автоматически возвращается к случаю 0?
Привет, @ B.Deaton, извините за поздний ответ. На самом деле, я видел ваше сообщение утром (по Индии, время по Гринвичу +5.30). Я обновил код, комментируя строки тегом «Новая строка». Пожалуйста, посмотрите ... !!! Если вы практикуетесь в iOS, было бы лучше иметь репозиторий GitHub, чтобы мы могли безупречно запускать ваш код на наших машинах.
Я изменил несколько вещей с момента вышеупомянутого вопроса. Я пытаюсь использовать всплывающий контроллер представления, чтобы изменить предпочтения пользователя на двух разных контроллерах представления.
Как вы показываете PopUpViewController из ViewController? Поделитесь кодом пожалуйста