【发布时间】:2020-09-11 15:47:56
【问题描述】:
我正在努力在 UITableViewCell 中正确使用 UISlider。 这是想法:
- 用户可以设置不同的作业,他需要完成任务。无法预先知道不同作业的数量。例如,用户 1 需要他的乐队只有吉他手和鼓手,而其他人需要吉他手、鼓手、歌手、键盘手等等。
我希望他提供的是,根据他需要的工作,他可以设置特定工作所需的人数。 我在 TableViewCell 中使用 UISlider 让他这样做。
但问题来了:
(1) 用户拖动 Slider 时 UISlider 下的 Label 没有显示正确的数量
(2) prepareForReuse 函数不能正常工作。我希望用户在使用重用单元时将 Slider 返回 0 并且 Label 显示 0。
(3) 最后,jobAmountNeeded Array 没有存储正确的值(或根本没有值),因此 Firebase 中保存的数量不正确。
在我看来,所有三个问题都连接到同一个源。
因此,如果有人可以帮助我,我会非常高兴。 :)
感谢大家的帮助!
class ProjectTeamViewController: UIViewController {
// MARK: - Properties
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var headerSeperator: UIView!
@IBOutlet weak var saveButton: UIButton!
var sortedSoloJobs = [String]()
var jobIndex: Int?
var jobAmount: [String] = []
var selectedJob:String?
var sentProjectCreated:String?
var projectCreated:String?
var jobAmountNeeded = [JobNeeded]()
var slider: [SliderClass] = []
let step:Float = 1
var selectedIndexPath: IndexPath?
var tempArray = [99: "Baum"]
var tempArray2 = [99: 5]
var currentValue:Float = 0
var key = 0
override func viewDidLoad() {
super.viewDidLoad()
setUpUI ()
getJobs(for: User.current) { (memberJobs) in
self.tableView.reloadData()
}
}
// MARK: - Functions
func setUpUI () {
Utilities.addShadowtoView(headerSeperator)
Utilities.addShadowtoButton(saveButton)
saveButton.layer.cornerRadius = 6
saveButton.layer.borderWidth = 1
saveButton.layer.borderColor = UIColor.darkGray.cgColor
}
func getJobs(for user: User, completion: @escaping ([MemberJobsStruct]) -> Void) {
var jobs = [String]() // All Jobs
var soloJobs = [String]() // Solo jobs from all jobs
let ref = Database.database().reference().child("team").child(user.uid)
ref.observeSingleEvent(of: .value, with: { snapshot in
for case let child as DataSnapshot in snapshot.children {
guard let value = child.value as? [String: Any] else {
return completion ([]) }
let memberJob = value["memberJob"] as! String
jobs.append(memberJob)
soloJobs = Array(Set(jobs))
self.sortedSoloJobs = soloJobs.sorted()
DispatchQueue.main.async { self.tableView.reloadData() }
} })
}
func json(from object:Any) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: object, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
@objc func sliderValueChange(sender: UISlider){
sender.isContinuous = false
currentValue = round(sender.value / step) * step
var sliderValue = Int(currentValue)
sender.value = currentValue // get slider's value
let row = sender.tag // get slider's row in table
key = row
if let row = self.jobAmountNeeded.firstIndex(where: {$0.jobKey == key}) {
jobAmountNeeded[row].jobAmount = sliderValue
}
}
@IBAction func saveAction(_ sender: Any) {
if projectCreated == nil || projectCreated == "no Value" {
let alert = UIAlertController(title: "Error", message: "Internal Error send a bug report: #150420", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
self.present(alert, animated: true)
} else {
for value in jobAmountNeeded {
let jobName = value.jobName
let jobAmount = value.jobAmount
let jobKey = value.jobKey
let currentUser = User.current
let jobreqRef = Database.database().reference().child("posts").child(currentUser.uid).child(projectCreated ?? "no Value").child("ProjectJobAmount").child(value.jobName)
let project = JobNeeded(jobName: jobName, jobAmount: jobAmount, jobKey: jobKey)
let projectDict = project.dictValue
jobreqRef.setValue(projectDict) { err, jobreqRef in
// print("done")
}
}
}
}
@IBAction func cancelAction(_ sender: Any) {
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
}
extension ProjectTeamViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sortedSoloJobs.count }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let sortedSoloJob = sortedSoloJobs[indexPath.row]
let key = indexPath.row
let cell = tableView.dequeueReusableCell(withIdentifier: "ProjectCharacterTableViewCell", for: indexPath) as! ProjectCharacterTableViewCell
cell.jobNameLabel.text = sortedSoloJobs[indexPath.row]
jobAmountNeeded.append(JobNeeded(jobName: sortedSoloJob, jobAmount: 0, jobKey: indexPath.section))
if let row = self.jobAmountNeeded.firstIndex(where: {$0.jobName == sortedSoloJob}) {
jobAmountNeeded[row].jobName = sortedSoloJob
}
tempArray.updateValue(sortedSoloJob, forKey: key)
let currentValue = cell.slider.value
cell.slider.isContinuous = false
cell.slider.tag = key
cell.slider.minimumValue = 0
cell.slider.maximumValue = Float(sortedSoloJob.count)
cell.slider.addTarget(self, action: #selector(sliderValueChange), for: .valueChanged)
cell.jobAmountLabel.text = "\(currentValue)"
return cell
}
}
// MARK: - UITableViewDelegate
extension ProjectTeamViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 163
}
}
class SliderClass: NSObject {
var title: String?
var subtitle: String?
var sliderMinimum: Float?
var sliderMaximum: Float?
init(title: String, subtitle: String, sliderMinimum: Float, sliderMaximum: Float) {
self.title = title
self.subtitle = subtitle
self.sliderMinimum = sliderMinimum
self.sliderMaximum = sliderMaximum
}
}
class ProjectCharacterTableViewCell: UITableViewCell {
@IBOutlet weak var jobAmountLabel: UILabel!
@IBOutlet weak var slider: UISlider!
@IBOutlet weak var jobNameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override public func prepareForReuse() {
// Ensures the reused cosmos view is as good as new
super.prepareForReuse()
self.jobAmountLabel.text = "0"
self.slider.value = 0
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
【问题讨论】:
-
虽然您可能是对的 - 三件事情以某种方式联系在一起 - 这是我通常会投票关闭的事情,因为看起来这些事情中的任何一件都没有联系。但我愿意帮忙。首先,我经常在表格单元格中使用滑块——它们有效。 (我想对您提出一些明确的建议,因为我不确定为什么您选择使用滑块是一个好的选择。)无论如何,把事情分解。例如,从事物中删除整个表格视图,只需将滑块和标签放在 UIView 中。 那个有用吗?如果不是,那么重复使用单元格不是问题。
-
感谢您的快速回复 :) 我非常感谢您没有关闭该主题并提供帮助 :) 在视图中它可以完美运行。您介意在 TableViewCell 中使用 UISlider 的地方发布您的“示例代码”吗?根据我的需要定制它,我认为我有能力......你会帮我一个大忙!
-
我看到你有一个你接受的答案。我仍然很乐意发布我的代码。我看到至少有两个可能使事情复杂化的差异。 (1)我不使用IB,只是直接代码。 (2) 我通过通知而不是回调传递滑块值。不管怎样,我很高兴你得到了你需要的帮助。 :-)
-
仍然感谢您的帮助!我是一个故事板孩子,因为我的应用程序是用于学术目的,它必须“快速简单”(至少使用直接代码更快更容易)仍然感谢您的帮助并且没有关闭主题! :)
标签: ios swift firebase uitableview uislider