CellView在

时间:2016-03-16 23:43:26

标签: swift tableview cell

我目前正在使用包含三个部分的tableview。每个部分从一个从后端加载的数组加载它的数据,并存储在本地数组中。数据下载和显示没有问题,但是一旦我滚动,单元格会重新加载它们以前的数据。在内存警告之外我抓住它的原因是单元格包含带阴影的图像,每个卷轴的阴影变暗。我觉得这个问题与我在indexPath上为每个部分调用单元格的方式有关,但似乎无法找到解决方案。我已经四处搜索,但还没能找到解决方案。

这些单元格共享相同的自定义类,并通过相同的插座重新加载它们各自的数据。 不确定这是否与问题相关,但是视图是从AppDelegate中的信息调用的。 这是我正在处理的代码,其中包含了部分行数。

覆盖func tableView(tableView:UITableView,numberOfRowsInSection section:Int) - > Int {

    if section == 0 {

        return likesName.count

    } else if section == 1 {

        return commentsName.count

    } else if section == 2 {

        return bookmarksName.count

}

    return 1
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = UITableViewCell()

    if indexPath.section == 0 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

    cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
    cell.userAvatar.clipsToBounds = true

    cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
    cell.artworkImage.clipsToBounds = true

    cell.artistName.text = likesName[indexPath.row]

    cell.information.text = "liked your artwork"

            likesImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            likesAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }


    } else if indexPath.section == 1 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

        cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
        cell.userAvatar.clipsToBounds = true

        cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
        cell.artworkImage.clipsToBounds = true

        cell.artistName.text = commentsName[indexPath.row]

        cell.information.text = commentsInformation[indexPath.row]

            commentsImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            commentsAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }


    } else if indexPath.section == 2 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

        cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
        cell.userAvatar.clipsToBounds = true

        cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
        cell.artworkImage.clipsToBounds = true

        cell.artistName.text = bookmarksName[indexPath.row]

         cell.information.text = "bookmarked your artwork"

            bookmarksImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            bookmarksAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }
        }


    return cell

}

3 个答案:

答案 0 :(得分:1)

排队代码有点困难,但看起来你有:

let cell = ...
if ... {
    let cell = ...
} else if ... {
    let cell = ...
}
return cell

如果这是您所拥有的内容,则每个let cell中的if仅限定在if内。因此,最后的return cell将返回初始的空单元格。如果是这种情况,您应该将其更改为:

if ... {
    let cell = ...
    return cell
} else if ... {
    let cell = ...
    return cell
} else {
    let cell = ...
    return cell
}

请注意,最后一个条件必须是else而不是else if,否则编译器会告诉您并非所有代码路径都返回一个值(最后一个"如果"失败) 。但是,你说它基本上是有效的,所以有些事情没有意义。

无论哪种方式,一旦一行离开屏幕,单元格就会被重新用于新行。因此,当您的getDataInBackgroundWithBlock返回时,该单元格可能属于另一行。鉴于阴影越来越暗,听起来像RightToggleCell中的代码在重复使用单元格时会重新运行。

在后台加载数据时,应将其存储在单元格之外,并在加载完成后重新加载该行。某事(非常粗略地)沿着以下几点:

likesImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in
    if let downloadedImage = UIImage(data: data!) {
        artworkImages[indexPath.row] = downloadedImage
        dispatch_async(dispatch_get_main_queue(), {
            tableView.reloadRowsAtIndexPaths([indexPath.row], withRowAnimation: true)
        })
    }
}

cellForRowAtIndexPath应显示相关的图片图像(如果可用),或者如果没有则使用上述代码。请注意,UI的任何更新都必须在主线程上完成,这就是上面调用dispatch_async的原因。

答案 1 :(得分:0)

我建议您将此代码放入" RightToggleCell"。

而不是在TableViewController上执行所有操作。
override func awakeFromNib() {

self.userAvatar.layer.cornerRadius =  self.userAvatar.frame.size.width/2
self.userAvatar.clipsToBounds = true

self.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
self.artworkImage.clipsToBounds = true

}

通过这样做,iOS每次重新加载TableView时都不会修改cornerRadius和clipsToBounds

答案 2 :(得分:0)

在迈克尔的指导下,我在每个if语句中移动了返回单元格,并在语句之外返回了UITableViewCell()并解决了问题。再次感谢迈克尔,我投了你的回复,但我没有足够的声誉来发布。