任何人都可以帮助确定我的问题吗?我正在尝试使用 UITable 和 Slider,强制两者之间进行交互。我想在表中选择一行,并让滑块显示与该行中的标签相对应的值,然后滑块应在更改时更新所选行中的标签。除了我启动测试应用程序时的第一个选择之外,它似乎运行良好。该行被选中,正确的值被传递到滑块中,但滑块值不显示传递给它的内容。
我这里有一个带有打印语句的示例。
当我在模拟器中运行代码并选择表中的第一行(第一个整数是 65)时,
didSelectRowAt
函数正确返回 65,并且 slider.value
设置为该值。但是,设置 slider.value
之后立即打印语句显示 1.0,并且应用程序上的滑块值为 1.0。
当我再次单击第一行时,该函数再次正确地将 65 识别为值,但这次滑块值正确设置为 65。如果我选择任何其他行,则应用程序可以正常运行。谁能看到我做错了什么,以致第一个选择不会更新滑块值?
我的代码在这里:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var slider: UISlider!{
didSet{
slider.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi/2))
}
}
@IBAction func sliderValueChanged(_ sender: Any) {
if selectedRowIndexPath == [] {return}//no row selected
let cell = tableView.cellForRow(at: selectedRowIndexPath)
let pField = cell?.contentView.viewWithTag(1) as? UILabel
pField?.text = String(format: "%d", Int(slider.value))
blendSolution[selectedRowIndexPath.row].p = Double(slider.value)
Swift.print(slider.value)
}
struct Gas {
var fO2, fHe, fN2, p, pCum, c, lO2, lHe, lN2 : Double
var desc = String()
init(fO2: Double, fHe: Double, p: Double, pCum: Double, c:Double){
self.fO2 = fO2
self.fHe = fHe
self.fN2 = 1 - fO2 - fHe
self.p = p
self.pCum = pCum
self.c = c
self.lO2 = fO2 * p * c
self.lHe = fHe * p * c
self.lN2 = (1 - fO2 - fHe) * p * c
self.desc = gasDesc(fO2: fO2, fHe: fHe)
}
func gasDesc(fO2: Double, fHe: Double) -> String {
if fO2 == 0.21 {return "Air"}
if fO2 == 1.0 {return "O2"}
if fHe == 1.0 {return "He"}
if fHe == 0 {return "EAN\(Int(round(fO2 * 100)))"}
return "\(Int(round(fO2 * 100)))/\(Int(round(fHe * 100)))"
}
}
var selectedRowIndexPath = IndexPath()
let startGas = Gas(fO2: 0.12, fHe: 0.50, p:45, pCum: 45, c: 3)
let targetGas = Gas(fO2: 0.16, fHe: 0.36, p:232, pCum: 232, c: 3)
var deltaGas = (lO2: Double(), lHe: Double(), lN2: Double())
var blendSolution = [Gas]()
var c = Double()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.isEditing = true
blendSolution = [
Gas(fO2: 0.17, fHe: 0.45, p:65.0, pCum: 65.0, c: 3),
Gas(fO2: 0.09, fHe: 0.65, p:40.0, pCum: 105.0, c: 3),
Gas(fO2: 0.12, fHe: 0.66, p:20.0, pCum: 125.0, c: 3),
Gas(fO2: 0.21, fHe: 0, p:30.0, pCum: 155.0, c: 3),
Gas(fO2: 0.0, fHe: 1.0, p:40.0, pCum: 195.0, c: 3),
Gas(fO2: 1.0, fHe: 0.0, p:15.0, pCum: 210.0, c: 3),
Gas(fO2: 0.32, fHe: 0.0, p:22.0, pCum: 232.0, c: 3)
]
c = targetGas.c
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return blendSolution.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "blendSolutionCell", for: indexPath)
let pField = cell.contentView.viewWithTag(1) as! UILabel
pField.text = String(Int(round(blendSolution[indexPath.row].p)))
let gasField = cell.contentView.viewWithTag(2) as! UILabel
gasField.text = String(blendSolution[indexPath.row].desc)
let pCum = cell.contentView.viewWithTag(3) as! UILabel
pCum.text = String(Int(round(blendSolution[indexPath.row].pCum)))
let intGas = cell.contentView.viewWithTag(4) as! UILabel
intGas.text = "Dummy"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Swift.print("value \( Float(blendSolution[indexPath.row].p))")
slider.value = Float(blendSolution[indexPath.row].p)
Swift.print("slider \(slider.value)")
slider.maximumValue = 232
slider.minimumValue = 0
selectedRowIndexPath = indexPath
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = self.blendSolution[sourceIndexPath.row]
blendSolution.remove(at: sourceIndexPath.row)
blendSolution.insert(movedObject, at: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
//disallow delete
return .none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
//remove indent when editing
return false
}
}
问题是,最初,滑块的最小值和最大值分别默认为 0.0 和 1.0。您直到稍后在
didSelectRowAt
中才更改滑块的最小值和最大值。将滑块的值设置为 didSelectRowAt
开头的值的尝试会标准化为当前的最小值和最大值。由于 65 大于 1.0,因此滑块的值强制为 1.0。然后,您设置新的最小值和最大值,以便将来对滑块的更改按预期工作。
简单的修复方法是将设置滑块最小值和最大值的代码移动到
didSet
属性的 slider
块。
@IBOutlet weak var slider: UISlider!{
didSet{
slider.transform = CGAffineTransform(rotationAngle: CGFloat(-Double.pi/2))
slider.maximumValue = 232
slider.minimumValue = 0
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Swift.print("value \( Float(blendSolution[indexPath.row].p))")
slider.value = Float(blendSolution[indexPath.row].p)
Swift.print("slider \(slider.value)")
selectedRowIndexPath = indexPath
}
或者您可以直接在情节提要中的滑块上设置最小值和最大值,而不是在代码中设置它们。