Ios 可重用的tableview单元相互影响,无需交互
我第一次尝试在Swift中完全以编程方式制作应用程序,但在使用UITableView时遇到了问题。 我创建了一个自定义的可重用单元,称为exerciseCell,其中有一个UILabel、一个UIImageview和一个UISwitch 我的问题是,当我选择第0行上的开关时,它也在打开第3行和第6行上的开关。这对每个细胞都是一样的,每个细胞影响大约三个细胞。 此tableview的目的是能够选择需要练习列表的练习,但每个练习都需要能够独立选择 以下是单元格的代码:Ios 可重用的tableview单元相互影响,无需交互,ios,swift,uitableview,uiswitch,Ios,Swift,Uitableview,Uiswitch,我第一次尝试在Swift中完全以编程方式制作应用程序,但在使用UITableView时遇到了问题。 我创建了一个自定义的可重用单元,称为exerciseCell,其中有一个UILabel、一个UIImageview和一个UISwitch 我的问题是,当我选择第0行上的开关时,它也在打开第3行和第6行上的开关。这对每个细胞都是一样的,每个细胞影响大约三个细胞。 此tableview的目的是能够选择需要练习列表的练习,但每个练习都需要能够独立选择 以下是单元格的代码: class exerciseC
class exerciseCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var cellSelected:Bool = false
let excersiseLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.red
label.textAlignment = NSTextAlignment.center
return label
}()
let excersiseImage: UIImageView = {
let image = UIImageView()
image.backgroundColor = UIColor.blue
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
let thisSwitch: UISwitch = {
let thisSwitch = UISwitch()
thisSwitch.isOn = false
thisSwitch.translatesAutoresizingMaskIntoConstraints = false
return thisSwitch
}()
func setupViews() {
addSubview(excersiseLabel)
addSubview(excersiseImage)
addSubview(thisSwitch)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["v0": excersiseLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-101-[v0(100)]-101-|", options: .alignAllCenterX, metrics: nil, views: ["v0": excersiseImage]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-120-[v0(100)]-120-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["v0": thisSwitch]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-12-[v0(30)]-8-[v1(100)]-12-[v2(30)]-12-|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": excersiseLabel, "v1": excersiseImage, "v2": thisSwitch]))
}
}
此外,cellForRow如下所示:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var thisCell = UITableViewCell()
if tableView == self.tableView {
let aCell = tableView.dequeueReusableCell(withIdentifier: "thirdCellID", for: indexPath) as! exerciseCell
aCell.excersiseLabel.text = "\(mobility[indexPath.row])"
aCell.thisSwitch.tag = indexPath.row
thisCell = aCell
}
return thisCell
}
如何让单元格独立响应用户?如果需要澄清,我可以提供更多代码。由于单元格被表视图重用,因此它们不会保留开关设置。您将需要一个外部构件来跟踪选择的单元格 单元格需要让您的控制器知道其开关何时被切换(可能是通过委托),此时您需要更新布尔的实例数组 然后,在cellForRowAtIndexPath中,需要一些代码将正确的值应用于单元格。比如:
cell.switch.isOn = cellSwitchStates[indexPath.row]
由于单元格被表视图重用,因此它们不会保留其开关设置。您将需要一个外部构件来跟踪选择的单元格 单元格需要让您的控制器知道其开关何时被切换(可能是通过委托),此时您需要更新布尔的实例数组 然后,在cellForRowAtIndexPath中,需要一些代码将正确的值应用于单元格。比如:
cell.switch.isOn = cellSwitchStates[indexPath.row]
这是uitableviewcell中显示的常见问题。解决此问题的最佳方法是使用对象配置单元 例如,在本例中,您需要在Tableview中显示练习列表。 因此,创建一个模态类,用于使用布尔变量进行练习,例如var switchState:Bool 然后使用默认的switchState值false填充练习对象数组,例如var exercises:[Exercise] 然后从练习数组中获取TableView numberofrows计数。。。返回练习。计数 在cellForRowAt indexPath中 从练习数组中获取正确的练习对象,例如:var exercise=exercises[indexath.row],现在我们有了正确的对象,对吗?因此,创建一个方法fun ConfigureCellWithExecute:在您的自定义单元格内进行练习,在您的案例中,单元格将是aCell 因此,从cellForRowAt indexPath调用此cell方法,并将我们的练习对象作为参数传递 e、 g.:aCell.configureCellWithexercise exerciseCell中的configureCellWith方法应该如下
// Write this method within exerciseCell
func configureCellWith(exercise:Exercise) {
privateExercise = exercise // privateExercise is a private Variable for exerciseCell so please create private var privateExercise : Exercise in exerciseCell
thisSwitch.isOn = exercise.switchState
}
然后在exerciseCell中为开关创建一个动作方法
thisSwitch.addTarget(self, action: Selector("switchTriggered:"), forControlEvents: .ValueChanged );
func switchTriggered(sender: AnyObject) {
let switch = sender as! UISwitch
privateExercise.switchState = switch.isOn
}
现在一切看起来都很好。。请务必打开/关闭第0行,并检查其是否影响其他行。谢谢。这是uitableviewcell中显示的常见问题。解决此问题的最佳方法是使用对象配置单元 例如,在本例中,您需要在Tableview中显示练习列表。 因此,创建一个模态类,用于使用布尔变量进行练习,例如var switchState:Bool 然后使用默认的switchState值false填充练习对象数组,例如var exercises:[Exercise] 然后从练习数组中获取TableView numberofrows计数。。。返回练习。计数 在cellForRowAt indexPath中 从练习数组中获取正确的练习对象,例如:var exercise=exercises[indexath.row],现在我们有了正确的对象,对吗?因此,创建一个方法fun ConfigureCellWithExecute:在您的自定义单元格内进行练习,在您的案例中,单元格将是aCell 因此,从cellForRowAt indexPath调用此cell方法,并将我们的练习对象作为参数传递 e、 g.:aCell.configureCellWithexercise exerciseCell中的configureCellWith方法应该如下
// Write this method within exerciseCell
func configureCellWith(exercise:Exercise) {
privateExercise = exercise // privateExercise is a private Variable for exerciseCell so please create private var privateExercise : Exercise in exerciseCell
thisSwitch.isOn = exercise.switchState
}
然后在exerciseCell中为开关创建一个动作方法
thisSwitch.addTarget(self, action: Selector("switchTriggered:"), forControlEvents: .ValueChanged );
func switchTriggered(sender: AnyObject) {
let switch = sender as! UISwitch
privateExercise.switchState = switch.isOn
}
现在一切看起来都很好。。请务必打开/关闭第0行,并检查其是否影响其他行。谢谢。非常感谢@Aby,这已经阻止了它们相互影响,但是如果我在tableview中向下滚动,然后向上滚动,开关将返回到关闭位置。我可能没有正确地处理私有变量,它不断给我错误关于没有分配一个exerciseName,所以我只是将名称初始化为。我想这是因为switchTriggered方法没有被识别。我在func中设置了一个打印开关,但它从未显示过。选择器样式正确吗?非常感谢@Aby,这已经阻止了它们相互影响,但是如果我在tableview中向下滚动,然后向上滚动,开关将返回到关闭位置。我可能没有正确地处理私有变量,它不断地给我关于no的错误
我没有指定exerciseName,所以我只是将名称初始化为。我想这是因为switchTriggered方法未被识别。我在func中设置了一个打印开关,但它从未显示过。选择器样式正确吗?