我正在编写一个小应用程序来计算曝光时间。
我有一个 UiViewController 通过三个 UiSwitch 设置 one Stop、halfStop 和 thridStop 的光圈。
如果将一个 UiSwitch 设置为 .isON == true,则另外两个开关设置为 .isOn == false。 这也很完美。
我还有一个按钮,可以用来返回到上一个ViewController。 UiSwitch 状态应通过点击此按钮来保存。
如果选择其中一个开关,则相应的数组应显示在 PickerView 中。
这对于单个数组来说效果很好,但我无法管理多个数组。
这就是问题所在,我在这里阅读了很多内容并尝试了很多,但就是行不通。
这是我迄今为止编写的代码:
光圈型号:
class ApertureModel {
var aperture: String
var f: Double
init(_aperture: String, _f: Double) {
self.aperture = _aperture
self.f = _f
}
}
光圈数据
import Foundation
class ApertureData {
class func DataOneStop() -> [ApertureModel] {
var dataAperture = [ApertureModel]()
dataAperture.append(ApertureModel(_aperture: "f:0.5", _f: 0.5))
dataAperture.append(ApertureModel(_aperture: "f:0.7", _f: 0.7))
dataAperture.append(ApertureModel(_aperture: "f:1.0", _f: 1.0))
dataAperture.append(ApertureModel(_aperture: "f:1.1", _f: 1.1))
dataAperture.append(ApertureModel(_aperture: "f:1.2", _f: 1.2))
dataAperture.append(ApertureModel(_aperture: "f:1.4", _f: 1.4))
dataAperture.append(ApertureModel(_aperture: "f:1.6", _f: 1.6))
dataAperture.append(ApertureModel(_aperture: "f:1.8", _f: 1.8))
dataAperture.append(ApertureModel(_aperture: "f:2.0", _f: 2.0))
dataAperture.append(ApertureModel(_aperture: "f:2.2", _f: 2.2))
dataAperture.append(ApertureModel(_aperture: "f:2.5", _f: 2.5))
dataAperture.append(ApertureModel(_aperture: "f:2.8", _f: 2.8))
dataAperture.append(ApertureModel(_aperture: "f:3.2", _f: 3.2))
dataAperture.append(ApertureModel(_aperture: "f:4.0", _f: 4.0))
dataAperture.append(ApertureModel(_aperture: "f:4.5", _f: 4.5))
dataAperture.append(ApertureModel(_aperture: "f:5.0", _f: 5.0))
dataAperture.append(ApertureModel(_aperture: "f:5.6", _f: 5.6))
dataAperture.append(ApertureModel(_aperture: "f:6.3", _f: 6.3))
dataAperture.append(ApertureModel(_aperture: "f:7.2", _f: 7.2))
dataAperture.append(ApertureModel(_aperture: "f:8.0", _f: 8.0))
dataAperture.append(ApertureModel(_aperture: "f:9.0", _f: 9.0))
dataAperture.append(ApertureModel(_aperture: "f:10", _f: 10.0))
dataAperture.append(ApertureModel(_aperture: "f:11", _f: 11.0))
dataAperture.append(ApertureModel(_aperture: "f:13", _f: 13.0))
dataAperture.append(ApertureModel(_aperture: "f:14", _f: 14.0))
dataAperture.append(ApertureModel(_aperture: "f:16", _f: 16.0))
dataAperture.append(ApertureModel(_aperture: "f:18", _f: 18.0))
dataAperture.append(ApertureModel(_aperture: "f:20", _f: 20.0))
dataAperture.append(ApertureModel(_aperture: "f:22", _f: 22.0))
dataAperture.append(ApertureModel(_aperture: "f:25", _f: 22.0))
dataAperture.append(ApertureModel(_aperture: "f:29", _f: 29.0))
dataAperture.append(ApertureModel(_aperture: "f:32", _f: 32.0))
dataAperture.append(ApertureModel(_aperture: "f:36", _f: 36.0))
dataAperture.append(ApertureModel(_aperture: "f:40", _f: 40.0))
dataAperture.append(ApertureModel(_aperture: "f:45", _f: 45.0))
dataAperture.append(ApertureModel(_aperture: "f:64", _f: 64.0))
dataAperture.append(ApertureModel(_aperture: "f:90", _f: 90.0))
dataAperture.append(ApertureModel(_aperture: "f:128", _f: 128.0))
dataAperture.append(ApertureModel(_aperture: "f:256", _f: 256.0))
dataAperture.append(ApertureModel(_aperture: "f:512", _f: 512.0))
dataAperture.append(ApertureModel(_aperture: "f:1024", _f: 1024.0))
return dataAperture
}
class func DataHalfStop() -> [ApertureModel] {
var dataAperture = [ApertureModel]()
dataAperture.append(ApertureModel(_aperture: "f/1.0", _f: 1.0))
dataAperture.append(ApertureModel(_aperture: "f/1.2", _f: 1.2))
dataAperture.append(ApertureModel(_aperture: "f/1.4", _f: 1.4))
dataAperture.append(ApertureModel(_aperture: "f/1.7", _f: 1.7))
dataAperture.append(ApertureModel(_aperture: "f/2.0", _f: 2.0))
dataAperture.append(ApertureModel(_aperture: "f/2.4", _f: 2.4))
dataAperture.append(ApertureModel(_aperture: "f/2.8", _f: 2.8))
dataAperture.append(ApertureModel(_aperture: "f/3.3", _f: 3.3))
dataAperture.append(ApertureModel(_aperture: "f/4.0", _f: 4.0))
dataAperture.append(ApertureModel(_aperture: "f/4.8", _f: 4.8))
dataAperture.append(ApertureModel(_aperture: "f/5.6", _f: 5.6))
dataAperture.append(ApertureModel(_aperture: "f/6.7", _f: 6.7))
dataAperture.append(ApertureModel(_aperture: "f/8.0", _f: 8.0))
dataAperture.append(ApertureModel(_aperture: "f/9.5", _f: 9.5))
dataAperture.append(ApertureModel(_aperture: "f/10", _f: 10.0))
dataAperture.append(ApertureModel(_aperture: "f/11", _f: 11.0))
dataAperture.append(ApertureModel(_aperture: "f/14", _f: 14.0))
dataAperture.append(ApertureModel(_aperture: "f/16", _f: 16.0))
dataAperture.append(ApertureModel(_aperture: "f/19", _f: 19.0))
dataAperture.append(ApertureModel(_aperture: "f/22", _f: 22.0))
dataAperture.append(ApertureModel(_aperture: "f/27", _f: 27.0))
dataAperture.append(ApertureModel(_aperture: "f/32", _f: 32.0))
dataAperture.append(ApertureModel(_aperture: "f/38", _f: 38.0))
dataAperture.append(ApertureModel(_aperture: "f/45", _f: 45.0))
dataAperture.append(ApertureModel(_aperture: "f/54", _f: 54.0))
dataAperture.append(ApertureModel(_aperture: "f/64", _f: 64.0))
dataAperture.append(ApertureModel(_aperture: "f/76", _f: 76.0))
dataAperture.append(ApertureModel(_aperture: "f/107", _f: 107.0))
dataAperture.append(ApertureModel(_aperture: "f/128", _f: 128.0))
dataAperture.append(ApertureModel(_aperture: "f/215", _f: 215.0))
dataAperture.append(ApertureModel(_aperture: "f/256", _f: 253.0))
dataAperture.append(ApertureModel(_aperture: "f/430", _f: 430.0))
dataAperture.append(ApertureModel(_aperture: "f/512", _f: 512.0))
dataAperture.append(ApertureModel(_aperture: "f/860", _f: 860.0))
dataAperture.append(ApertureModel(_aperture: "f/1024", _f: 1024.0))
return dataAperture
}
class func DataThirdStop() -> [ApertureModel] {
var dataAperture = [ApertureModel]()
dataAperture.append(ApertureModel(_aperture: "f/1.0", _f: 1.0))
dataAperture.append(ApertureModel(_aperture: "f/1.4", _f: 1.4))
dataAperture.append(ApertureModel(_aperture: "f/2.0", _f: 2.0))
dataAperture.append(ApertureModel(_aperture: "f/2.8", _f: 2.8))
dataAperture.append(ApertureModel(_aperture: "f/4.0", _f: 4.0))
dataAperture.append(ApertureModel(_aperture: "f/5.6", _f: 5.6))
dataAperture.append(ApertureModel(_aperture: "f/8.0", _f: 8.0))
dataAperture.append(ApertureModel(_aperture: "f/11", _f: 11.0))
dataAperture.append(ApertureModel(_aperture: "f/16", _f: 16.0))
dataAperture.append(ApertureModel(_aperture: "f/22", _f: 22.0))
dataAperture.append(ApertureModel(_aperture: "f/32", _f: 32.0))
dataAperture.append(ApertureModel(_aperture: "f/45", _f: 45.0))
dataAperture.append(ApertureModel(_aperture: "f/64", _f: 64.0))
dataAperture.append(ApertureModel(_aperture: "f/90", _f: 90.0))
dataAperture.append(ApertureModel(_aperture: "f/128", _f: 128.0))
dataAperture.append(ApertureModel(_aperture: "f/256", _f: 256.0))
dataAperture.append(ApertureModel(_aperture: "f/512", _f: 512.0))
dataAperture.append(ApertureModel(_aperture: "f/1024", _f: 1024.0))
return dataAperture
}
}
选择器视图
import UIKit
class SelectAperture: UIViewController {
@IBOutlet weak var aperturePicker: UIPickerView!
var delegateAperture: apertureDelegate? = nil
var apertureModelThird = [ApertureModel]()
let defaults = UserDefaults.standard
//MARK: - Unwind
@IBAction func unwindAperture(_ sender: UIStoryboardSegue) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
aperturePicker.dataSource = self
aperturePicker.delegate = self
apertureModelThird = ApertureData.DataOneStop()
//MARK: - Notification
if let selectedRow = defaults.object(forKey: "saveAperturePicker") as? Int {
aperturePicker.selectRow(selectedRow, inComponent: 0, animated: true)
}
NotificationCenter.default.addObserver(self, selector: #selector(aperturePickerChanged), name: Notification.Name.pickersChanged, object: nil)
}
//MARK: - Func PickerChanced
@objc func aperturePickerChanged() {
let values = aperturePicker.selectedRow(inComponent: 0)
_ = apertureModelThird[values...values]
}
}
//MARK: - PickerView Delegate
extension SelectAperture: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
apertureModelThird[row].aperture
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
NotificationCenter.default.post(name: Notification.Name.pickersChanged, object: self)
//MARK: - Speicherung der PickerRow
let rowDefaults = defaults
rowDefaults.set(row, forKey: "saveAperturePicker")
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerText = UILabel()
pickerText.textColor = UIColor.white
pickerText.text = apertureModelThird[row].aperture
pickerText.font = UIFont.boldSystemFont(ofSize: 20)
pickerText.textAlignment = NSTextAlignment.center
return pickerText
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
30
}
}
//MARK: - PickerView DataSource
extension SelectAperture: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
apertureModelThird.count
}
}
//MARK: - Extension Notification
extension Notification.Name {
static let pickersChanged = Notification.Name("PickerChanged")
}
//MARK: - Delegate
protocol apertureDelegate {
func apertureValue(aperture: String)
}
UI开关
import UIKit
class SelectApertureStops: UIViewController {
@IBOutlet weak var oneStopSwitch: UISwitch!
@IBOutlet weak var halfStopSwitch: UISwitch!
@IBOutlet weak var thirdStopSwitch: UISwitch!
let switchDelfault = UserDefaults.standard
//MARK: - Unwind
@IBAction func unwindStops(_ sender: UIStoryboardSegue) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
oneStopSwitch.isOn = switchDelfault.bool(forKey: "switchStateOne")
halfStopSwitch.isOn = switchDelfault.bool(forKey: "switchStateHalf")
thirdStopSwitch.isOn = switchDelfault.bool(forKey: "switchStateThird")
}
@IBAction func oneStopSwitchChanged(_ sender: UISwitch) {
if (sender.isOn == true) {
halfStopSwitch.isOn = false
thirdStopSwitch.isOn = false
} else if sender.isOn == false && halfStopSwitch.isOn == false && thirdStopSwitch.isOn == false {
oneStopSwitch.isOn = true
}
switchDelfault.set(sender.isOn, forKey: "switchStateOne")
}
@IBAction func halfStopSwitchChanged(_ sender: UISwitch) {
if sender.isOn == true {
oneStopSwitch.isOn = false
thirdStopSwitch.isOn = false
} else if oneStopSwitch.isOn == false && halfStopSwitch.isOn == false && thirdStopSwitch.isOn == false {
halfStopSwitch.isOn = true
}
switchDelfault.set(sender.isOn, forKey: "switchStateHalf")
}
@IBAction func thirdStopSwitchChanged(_ sender: UISwitch) {
if sender.isOn == true {
oneStopSwitch.isOn = false
halfStopSwitch.isOn = false
} else if oneStopSwitch.isOn == false && halfStopSwitch.isOn == false && thirdStopSwitch.isOn == false {
thirdStopSwitch.isOn = true
}
switchDelfault.set(sender.isOn, forKey: "switchStateThird")
}
}
如果您能帮助我,我会非常高兴,因为我无法再进一步了。
我仍然是 Swift5 的初学者,在此期间我学到了很多东西,但不幸的是我在这个问题上失败了。
下面的解决方案提供了解决您概述的问题的简化方法。
它使用枚举来跟踪活动开关,然后使用它通过
pickerView(_:titleForRow:forComponent:)
委托方法和开关状态来驱动选择器内容的更新。
它还使用单一方法来处理所有 3 个开关中的更改。在下面的代码中,我使用代码生成 UI 组件,因此它形成了一个工作示例。您需要对其进行调整以适应您的 IB 元素。
[我刚刚将 UI 元素放入堆栈视图中以保持简单]
class TempVC : UIViewController {
enum ActiveSwitch {
case s1, s2, s3
}
lazy var switch1 = UISwitch(frame: .zero, primaryAction: UIAction(title: "S1", handler: switchesChanged))
lazy var switch2 = UISwitch(frame: .zero, primaryAction: UIAction(title: "S2", handler: switchesChanged))
lazy var switch3 = UISwitch(frame: .zero, primaryAction: UIAction(title: "S3", handler: switchesChanged))
//quick and dirty data sources for each option
let switch1Data = ["s1L1", "s1L2", "s1L3", "s1L4", "s1L5"]
let switch2Data = ["s2L1", "s2L2", "s2L3", "s2L4", "s2L5"]
let switch3Data = ["s3L1", "s3L2", "s3L3", "s3L4", "s3L5"]
lazy var picker = UIPickerView()
//just for display purposes, not functionally relevant to the question
lazy var sStack = {
let stack = UIStackView(arrangedSubviews: [switch1, switch2, switch3])
stack.axis = .horizontal
stack.alignment = .center
stack.distribution = .equalSpacing
stack.spacing = 20
return stack
}()
//just for display purposes, not functionally relevant to the question
lazy var vStack = {
let stack = UIStackView(arrangedSubviews: [sStack, picker])
stack.axis = .vertical
stack.translatesAutoresizingMaskIntoConstraints = false
return stack
}()
var activeSwitch = ActiveSwitch.s1 {
didSet {
setSwitches(for: activeSwitch)
picker.reloadAllComponents()
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
picker.delegate = self
picker.dataSource = self
setSwitches(for: activeSwitch)
view.addSubview(vStack)
NSLayoutConstraint.activate([
vStack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
vStack.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
vStack.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 50),
vStack.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -50),
])
}
func switchesChanged(_ action: UIAction) {
switch action.sender as! UISwitch {
case switch1: activeSwitch = .s1
case switch2: activeSwitch = .s2
case switch3: activeSwitch = .s3
default: fatalError()
}
}
func setSwitches(for active: ActiveSwitch) {
switch1.setOn(active == .s1, animated: true)
switch2.setOn(active == .s2, animated: true)
switch3.setOn(active == .s3, animated: true)
}
}
extension TempVC: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int ) -> String? {
return switch activeSwitch {
case .s1: switch1Data[row]
case .s2: switch2Data[row]
case .s3: switch3Data[row]
}
}
}
extension TempVC: UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 5 }
}