如何保存多个 UISwitch,从而显示 Pickerview 的不同数组?

问题描述 投票:0回答:1

我正在编写一个小应用程序来计算曝光时间。

我有一个 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 的初学者,在此期间我学到了很多东西,但不幸的是我在这个问题上失败了。

swift uikit uipickerview uiswitch savechanges
1个回答
0
投票

下面的解决方案提供了解决您概述的问题的简化方法。

它使用枚举来跟踪活动开关,然后使用它通过

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 }
}
© www.soinside.com 2019 - 2024. All rights reserved.