从 tableViewCell 访问存储的值并将它们保存到 firebaseDatabase

access stored values from a tableViewCell and save them to firebaseDatabase

我有一个 tableViewCell,里面有一个范围滑块。当用户点击 handleSave() 时,我希望将范围滑块的值保存到 firebase。当用户在 tableViewCell 中滑动范围滑块时,我可以打印出这些值,但是我无法从 tableViewCell 本身保存这个值,也无法从 tableViewVC 打印这些值。当我尝试从 tableViewVC 打印值时,我在控制台中看不到任何内容。但是,如果我要从我的 tableViewCell 本身打印它们,那么它就可以正常工作。

我用来尝试打印 tableViewVC 中的值的代码是,

   if indexPath.section == 2 {
        
        let costRangeCell = AgeRangeCell(style: .default, reuseIdentifier: nil)
        costRangeCell.rangeSlider.minimumValue = 5
        costRangeCell.rangeSlider.maximumValue = 200
        costRangeCell.rangeSlider.lowValue = 5
        costRangeCell.rangeSlider.highValue = 200
        costRangeCell.rangeSlider.minimumDistance = 20
        costRangeCell.delegate = self
        
        return costRangeCell
    }


var lowCost: Double = 0.0
var highCost: Double = 0.0

func didChange(lowVal: Double, highVal: Double, forCell cell: AgeRangeCell) {
    self.lowCost = lowVal
    self.highCost = highVal
}

在上面的打印语句中,我可以看到用户选择的范围滑块的值。

以及我打算如何保存数据也在 tableViewVc 中。

    @objc fileprivate func handleSave() {
       guard let uid = Auth.auth().currentUser?.uid else { return }
    let docData: [String: Any] = [
        "minSeekingCost": lowCost,
        "maxSeekingCost": highCost
        
    ]
    
    self.updateUserDataIntoDatabseWithUID(uid: uid, values: docData as [String : AnyObject])
    print("Finished saving user info")
    self.dismiss(animated: true, completion: {
        print("Dismissal complete")
        print(lowVal)
        print(highVal)
    })
}

当我尝试查看此处打印的值时,它只显示 0 和 1 而不是 rangeSlider 的实际编号

   protocol AgeRangeCellDelegate {
func didChange(lowVal: Double, highVal: Double, forCell cell: AgeRangeCell)
 }

 class AgeRangeCell: UITableViewCell {

let rangeSlider: AORangeSlider = {
    let slider = AORangeSlider()
    slider.stepValue = 5
    slider.trackColor = GREEN_Theme
    slider.addTarget(self, action: #selector(didChangeCost), for: .touchUpInside)
    return slider
}()

var delegate: AgeRangeCellDelegate?
var user: User?
let lowLabel = UILabel()
let highLabel = UILabel()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    commonInit()
}

@objc func didChangeCost(_ sender: AORangeSlider) {
    delegate?.didChange(lowVal: sender.lowValue, highVal: sender.highValue, forCell: self)
        }

required init?(coder: NSCoder) {
    super.init(coder: coder)

   }

 }

当打印语句在 ageRangeCell 内部时,我可以成功打印范围滑块的值。但是当我尝试在 tableViewVC 中打印 rangeSliders 值时,它不起作用。我将此信息保存到 firebase 的唯一方法是我是否可以访问它的值。我错过了什么?如果我可以在 tableViewVC 中打印语句,我就可以将它们保存到数据库中。

您的代码有问题

  1. handelSave 方法中,当您尝试从单元格中获取值时,您希望获得用户创建的滑块值,但实际上您正在创建新的具有默认值的 AgeRangeCell 实例。要解决此问题,您需要像我一样使用 delegation 模式 post。

    删除 handleSave 方法中的这一行: let costRangeCell = AgeRangeCell(style: .default, reuseIdentifier: nil)

    对于 class 中的 minSeekingCost 和 maxSeekingCost 值,必须创建附加参数来保存此值。

  2. 创建 AgeRangeCell 时,您没有传递重用标识符,这会导致 table 视图滚动性能变慢。

可能的解决方案

  1. 使用 MVC 和委托模式。你需要有适合你年龄的价值持有者。下面是如何实现的示例。
  2. 使用 SwiftUI 构建 UI。与 Combine 一起,它允许消除委派模式。

出于这个原因,我确实使用了故事板,因为需要的代码更少。

AgeRangeCell 和 AgeRangeCellDelegate

protocol AgeRangeCellDelegate {
    func didChange(age: Float, forCell cell: AgeRangeCell)
}

class AgeRangeCell: UITableViewCell {
    
    var delegate: AgeRangeCellDelegate?
    
    @IBOutlet weak var slider: UISlider!
    
    @IBAction func didChangeAge(_ sender: UISlider) {
        delegate?.didChange(age: sender.value, forCell: self)
    }
}

ViewController

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    
    var age: Float = 0
    
    @IBAction func didTapSave(_ sender: Any) {
        // TODO: Save age to Firestore
        
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let docData: [String: Any] = [
            "age": age
        ]
        
        updateUserDataIntoDatabseWithUID(uid: uid, values: docData as [String : AnyObject])
    }
}

UITableViewDataSource

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        1
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "AgeRangeCell") as! AgeRangeCell
        
        cell.delegate = self
        cell.slider.value = age
        
        return cell
    }
}

AgeRangeCellDelegate

extension ViewController: AgeRangeCellDelegate {
    func didChange(age: Float, forCell cell: AgeRangeCell) {
        self.age = age
    }
}