从 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 中打印语句,我就可以将它们保存到数据库中。
您的代码有问题
在 handelSave 方法中,当您尝试从单元格中获取值时,您希望获得用户创建的滑块值,但实际上您正在创建新的具有默认值的 AgeRangeCell 实例。要解决此问题,您需要像我一样使用 delegation 模式 post。
删除 handleSave 方法中的这一行:
let costRangeCell = AgeRangeCell(style: .default, reuseIdentifier: nil)
对于 class 中的 minSeekingCost 和 maxSeekingCost 值,必须创建附加参数来保存此值。
创建 AgeRangeCell 时,您没有传递重用标识符,这会导致 table 视图滚动性能变慢。
可能的解决方案
- 使用 MVC 和委托模式。你需要有适合你年龄的价值持有者。下面是如何实现的示例。
- 使用 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
}
}
我有一个 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 中打印语句,我就可以将它们保存到数据库中。
您的代码有问题
在 handelSave 方法中,当您尝试从单元格中获取值时,您希望获得用户创建的滑块值,但实际上您正在创建新的具有默认值的 AgeRangeCell 实例。要解决此问题,您需要像我一样使用 delegation 模式 post。
删除 handleSave 方法中的这一行: let costRangeCell = AgeRangeCell(style: .default, reuseIdentifier: nil)
对于 class 中的 minSeekingCost 和 maxSeekingCost 值,必须创建附加参数来保存此值。
创建 AgeRangeCell 时,您没有传递重用标识符,这会导致 table 视图滚动性能变慢。
可能的解决方案
- 使用 MVC 和委托模式。你需要有适合你年龄的价值持有者。下面是如何实现的示例。
- 使用 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
}
}