我有一个PopUpViewController,当在主ViewController中按下按钮时会弹出。我在三个不同的ViewController上有一个speedDisplay(UILabel),我希望能够在MPH和KMH之间切换输出,但我不知道该怎么做。我在PopUpViewController中有一个segmentControl,我正在尝试实现这一点。有人可以帮我从这里出去吗?
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()
}
答案 0 :(得分: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
}
}