问题
I'm currently trying to connect two UISegmentedControls where the first Viewcontroller is connected to the second. Tapping the second UISegment will update the value of the first one.
ViewController:
class ViewController: UIViewController {
@IBOutlet weak var tipLabel: UILabel!
@IBOutlet weak var totalLabel: UILabel!
@IBOutlet weak var billField: UITextField!
@IBOutlet weak var tipController: UISegmentedControl!
@IBOutlet weak var splitController: UISegmentedControl!
@IBOutlet weak var splitLabel: UILabel!
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
defaults.synchronize()
billField.becomeFirstResponder()
tipController.selectedSegmentIndex = defaults.integer(forKey: "default_tip_index")
print(tipController.selectedSegmentIndex)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// @IBAction func toSettings(_ sender: Any) {
// self.performSegue(withIdentifier: "toSettings", sender: self)
// }
@IBAction func onTap(_ sender: Any) {
view.endEditing(true)
}
@IBAction func calculateTip(_ sender: Any) {
let tipPercentages = [0.18, 0.20, 0.25]
let splitNumbers = [1,2,3,4]
let bill = Double(billField.text!) ?? 0
let tip = bill * tipPercentages[tipController.selectedSegmentIndex]
let total = bill + tip
tipLabel.text = String(format: "$%.2f", tip)
totalLabel.text = String(format: "$%.2f", total)
splitLabel.text = String(format: "$%.2f", total/Double((splitNumbers[splitController.selectedSegmentIndex])))
}
SettingViewController:
class SettingsViewController: UIViewController {
var tipPercentageIndex:Int!
@IBOutlet weak var settingsTipController: UISegmentedControl!
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
settingsTipController.selectedSegmentIndex = defaults.integer(forKey: "default_tip_index")
// Do any additional setup after loading the view.
}
@IBAction func Index(_ sender: Any) {
tipPercentageIndex = settingsTipController.selectedSegmentIndex
}
@IBAction func saveButton(_ sender: Any) {
tipPercentageIndex = settingsTipController.selectedSegmentIndex
defaults.set(tipPercentageIndex, forKey: "default_tip_index")
defaults.synchronize()
self.performSegue(withIdentifier: "Tippy", sender: self)
}
@IBAction func Back(_ sender: Any) {
self.performSegue(withIdentifier: "Tippy2", sender: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
However, my solution does not update the value nor store the value when switching back from the second to the first.
Note: the first segues to the second.
回答1:
Add an IBAction for Value Changed
for the segmented controls, and update values for the affected controls:
func updateSegments(){
if let value = UserDefaults.standard.value(forKey: "key"){
let selectedIndex = value as! Int
yourSegmentedControl.selectedSegmentIndex = selectedIndex
} else {
yourSegmentedControl.selectedSegmentIndex = 0 // set to default
}
if let value = UserDefaults.standard.value(forKey: "anotherkey"){
let selectedIndex = value as! Int
anotherSegmentedControl.selectedSegmentIndex = selectedIndex
} else {
anotherSegmentedControl.selectedSegmentIndex = 0 // set to default
}
//etc...
}
@IBAction func yourSegmentedControlSelected(_ sender: UISegmentedControl) {
UserDefaults.standard.set(sender.selectedSegmentIndex, forKey: "key")
self.updateSegments()
}
@IBAction func anotherSegmentedControlSelected(_ sender: UISegmentedControl) {
UserDefaults.standard.set(sender.selectedSegmentIndex, forKey: "anotherkey")
self.updateSegments()
}
回答2:
From how you've explained your code, I think your problem is that the code that loads your dependent values, is only called when your viewController is loaded. And I believe, the viewController you are "switching back" to, has already been loaded. So the set up code will not be executed again after updating your defaults.
One quick fix to try is moving your set up code for viewDidLoad
to viewWillAppear
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
defaults.synchronize()
billField.becomeFirstResponder()
tipController.selectedSegmentIndex = defaults.integer(forKey: "default_tip_index")
print(tipController.selectedSegmentIndex)
}
Update Just noticed you said the value is not stored, along with my pervious suggestion try this—
Create a method that sets the defaults to the settingsTipController.selectedSegmentIndex
. When you load the SettingsViewController
, add the method as a target to the settingsTipController
that acts on a .valueChanged
event.
When save is tapped the last selected value will be saved.
In SettingsViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
settingsTipController.selectedSegmentIndex = defaults.integer(forKey: "default_tip_index")
settingsTipController.addTarget(nil, action: #selector(didToggleSwitch), for: .valueChanged)
}
@objc func didToggleSwitch() {
tipPercentageIndex = settingsTipController.selectedSegmentIndex
defaults.set(tipPercentageIndex, forKey: "default_tip_index")
}
@IBAction func saveButton(_ sender: Any) {
tipPercentageIndex = settingsTipController.selectedSegmentIndex
defaults.set(tipPercentageIndex, forKey: "default_tip_index")
defaults.synchronize()
self.performSegue(withIdentifier: "Tippy", sender: self)
}
来源:https://stackoverflow.com/questions/48047967/linking-two-uisegmentedcontrols