Ios 滚动时,添加到UITableViewCell的图像显示在错误的行中
我在选择一个表视图行时将其添加到表视图行(实际上,我似乎将其添加到该行的单元格中)(再次选择时将其删除)。表格视图由原型单元组成 这是可行的,但当我滚动并返回到我先前选择的行时,图像将位于另一行。此外,图像也显示在其他行中 我猜这是因为滚动时单元格被重复使用。 下面是一个小示例项目的代码:Ios 滚动时,添加到UITableViewCell的图像显示在错误的行中,ios,swift,uitableview,Ios,Swift,Uitableview,我在选择一个表视图行时将其添加到表视图行(实际上,我似乎将其添加到该行的单元格中)(再次选择时将其删除)。表格视图由原型单元组成 这是可行的,但当我滚动并返回到我先前选择的行时,图像将位于另一行。此外,图像也显示在其他行中 我猜这是因为滚动时单元格被重复使用。 下面是一个小示例项目的代码: import UIKit class MyTableViewController: UITableViewController { // Using integers for simplicity,
import UIKit
class MyTableViewController: UITableViewController {
// Using integers for simplicity, should work with strings, too.
var numbers = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
numbers.append(i)
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(numbers[indexPath.row] + 1)"
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numbers.count
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if let myImage = curCell.viewWithTag(10) as? MyImage {
myImage.removeFromSuperview()
} else {
let myImage = myImage()
myImage.tag = 10
cell.addSubview(myImage)
}
}
导入UIKit
类MyTableViewController:UITableViewController{
//为了简单起见,使用整数也可以处理字符串。
变量编号=[Int]()
重写func viewDidLoad(){
super.viewDidLoad()
对于0..UITableViewCell中的i{
让cell=tableView.dequeueReusableCellWithIdentifier(“TestCell”,forIndexPath:indexPath)
cell.textlab?.text=“\(数字[indexPath.row]+1)”
返回单元
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回数字。计数
}
重写func tableView(tableView:UITableView,didSelectRowAtIndexPath:nsindepath){
让cell=tableView.cellforrowatinexpath(indexPath)!
如果让myImage=curCell.viewWithTag(10)作为?myImage{
myImage.removeFromSuperview()文件
}否则{
让myImage=myImage()
myImage.tag=10
cell.addSubview(myImage)
}
}
我需要让图像保持在正确的行中,当回到这个视图控制器时也是如此。解决这个问题的正确方法是什么?
非常感谢任何建议
编辑:我试图实现matt的答案,但我似乎遗漏了一些东西,因为问题仍然是一样的
编辑2:已更新,正在按预期工作
import UIKit
class ListItem {
var name: String!
var showsImage = false
init(name: String) {
self.name = name
}
}
class MyTableViewController: UITableViewController {
var listItems = [ListItem]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
let listItem = ListItem(name: "row \(i)")
listItems.append(listItem)
}
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(listItems[indexPath.row].name)"
if listItems[indexPath.row].showsImage {
let myImage = myImage
myImage.tag = 10
cell.addSubview(myImage)
} else {
if let myImage = cell.viewWithTag(10) as? myImage {
myImage.removeFromSuperview()
listItems[indexPath.row].showsImage = false
}
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listItems.count
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if let myImage = cell.viewWithTag(10) as? myImage {
myImage.removeFromSuperview()
listItems[indexPath.row].showsImage = false
} else {
listItems[indexPath.row].showsImage = true
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
}
}
导入UIKit
类列表项{
变量名称:字符串!
var showsImage=false
init(名称:String){
self.name=名称
}
}
类MyTableViewController:UITableViewController{
变量listItems=[ListItem]()
重写func viewDidLoad(){
super.viewDidLoad()
对于0..UITableViewCell中的i{
让cell=tableView.dequeueReusableCellWithIdentifier(“TestCell”,forIndexPath:indexPath)
cell.textLabel?.text=“\(listItems[indexPath.row].name)”
如果listItems[indexath.row].showsImage{
让myImage=myImage
myImage.tag=10
cell.addSubview(myImage)
}否则{
如果让myImage=cell.viewWithTag(10)作为?myImage{
myImage.removeFromSuperview()文件
listItems[indexath.row].showsImage=false
}
返回单元
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回listItems.count
}
重写func tableView(tableView:UITableView,didSelectRowAtIndexPath:nsindepath){
让cell=tableView.cellforrowatinexpath(indexPath)!
如果让myImage=cell.viewWithTag(10)作为?myImage{
myImage.removeFromSuperview()文件
listItems[indexath.row].showsImage=false
}否则{
listItems[indexath.row].showsImage=true
tableView.reloadRowsAtIndexPaths([indexPath],withRowAnimation:.None)
}
}
}
编辑3:正如matt所建议的,下面是代码的另一种解决方案,上面的代码将UITableViewCell子类化,而不是对图像使用标记
import UIKit
class MyTableViewCell: UITableViewCell {
var myImage = MyImage()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
myImage.hidden = true
addSubview(myImage)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ListItem {
var name: String!
var showsImage = false
init(name: String) {
self.name = name
}
}
class MyTableViewController: UITableViewController {
var listItems = [ListItem]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
let listItem = ListItem(name: "row \(i)")
listItems.append(listItem)
}
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = MyTableViewCell(style: .Default, reuseIdentifier: "TestCell")
cell.textLabel?.text = "\(listItems[indexPath.row].name)"
cell.myImage.hidden = !(listItems[indexPath.row].showsImage)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell
listItems[indexPath.row].showsImage = cell.myImage.hidden
cell.myImage.hidden = !cell.myImage.hidden
}
}
导入UIKit
类MyTableViewCell:UITableViewCell{
var myImage=myImage()
重写初始化(样式:UITableViewCellStyle,reuseIdentifier:String?){
init(样式:style,reuseIdentifier:reuseIdentifier)
myImage.hidden=true
添加子视图(myImage)
}
必需的初始化?(编码器aDecoder:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
}
类列表项{
变量名称:字符串!
var showsImage=false
init(名称:String){
self.name=名称
}
}
类MyTableViewController:UITableViewController{
变量listItems=[ListItem]()
重写func viewDidLoad(){
super.viewDidLoad()
对于0..Int中的i{
返回listItems.count
}
重写func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格{
let cell=MyTableViewCell(样式:。默认值,reuseIdentifier:“TestCell”)
cell.textLabel?.text=“\(listItems[indexPath.row].name)”
cell.myImage.hidden=!(列表项[indexath.row].showsImage)
返回单元
}
重写func tableView(tableView:UITableView,didSelectRowAtIndexPath:nsindepath){
将cell=tableView.cellforrowatinexpath(indexPath)设为!MyTableViewCell
listItems[indexPath.row].showsImage=cell.myImage.hidden
cell.myImage.hidden=!cell.myImage.hidden
}
}
问题在于,单元格在其他行中被重用。当它们被重用时,将再次调用cellForRowAtIndexPath
。但当它被重用时,您没有提供有关该行的图像的信息
解决方案:修复您的模型(即您在
cellforrowatinexpath
中查阅的信息)这样它就能了解图像。在didSelect
中,不要直接修改单元格。相反,请修改模型并重新加载单元格。嗨,matt,非常感谢你的帮助。我已经尝试实现你的答案,并将代码示例添加到我的帖子中。我仍然在做一些错误的事情,如果你能快速查看一下,那将是非常好的。Tha谢谢!很好!你就快到了。你只是犯了一个小小的逻辑错误。你的cellForRow
有这样一个条件:if listItems[indexath.row].showsImage
,但您忘记了说明否则会发生什么。您需要添加一个删除图像的else
子句。在这一点上,我认为一切都将开始就绪。换句话说,请记住cellForRow
必须完全配置每个单元格,因为您永远不知道该单元格是否正确正在重复使用。-另外,请注意,您现在可能会重复向同一单元格添加多个图像视图。T