【问题标题】:TableView Cell with Minor Lag (Async Proper Use?) SwiftTableView Cell with Minor Lag (Async Proper Use?) Swift
【发布时间】:2018-03-21 06:17:38
【问题描述】:

我有一个 充满数据的数组tableView 单元格中加载图像。但是我得到了轻微的滞后(更多的故障)当表格视图在图像索引上滚动时。

数组包含数据(似乎滞后更大的字节)

以字节为单位的数据(624230 字节)

以字节为单位的数据(1619677 字节)

以字节为单位的数据(2257181 字节)

以字节为单位的数据(1120275bytes)

不确定如何在加载数据时正确使用 Async。

struct messageCellStruct {

    let message: String!
    let photoData: Data!

}

var messageArray = [messageCellStruct]()



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")


        let message2 = cell?.viewWithTag(2) as! UITextView


        var photoUploadData = messageArray[indexPath.row].photoData

        let main = DispatchQueue.main
        let background = DispatchQueue.global()
        let helper = DispatchQueue(label: "another_thread")



        if(photoUploadData != nil){

            print("Data in Bytes\(String(describing: photoUploadData))")



                    let fullString = NSMutableAttributedString(string: "")
                    let image1Attachment = NSTextAttachment()
                    let newImageWidth = (self.message.bounds.size.width - 20 )
                    let messageDisplayString = self.messageArray[indexPath.row].message

            background.async {
                    image1Attachment.image = UIImage(data: photoUploadData!)
            }


                    image1Attachment.bounds = CGRect.init(x: 0, y: 0, width: newImageWidth, height: 200)


                    let image1String = NSAttributedString(attachment: image1Attachment)


                    fullString.append(image1String)
                    fullString.append(NSAttributedString(string: messageDisplayString!))

                    message2.attributedText = fullString
                    message2.textColor = .white
                    message2.font = UIFont.systemFont(ofSize: 17.0)


        }else {

            message2.text = self.messageArray[indexPath.row].message

        }




        return cell!
    }

我首先引入 Async 的原因是因为滞后。无论有没有异步,它都会滞后。

【问题讨论】:

  • 你为什么不简单地使用SDWebImage 来加载表格单元格中的图像。 UI 工作永远不应该在 backgroundQueue 中完成。如果您在后台下载任何数据,则在显示时执行mainQueue
  • 我有 Alamofire 但我不知道如何将 SDWebImage 或 AlamoFire 与 NSAttachment 集成。它们非常适合 UIImageViews。
  • 此外,如果您在cellForRowAtIndexPath: 方法中执行下载任务,您将不得不处理正在进行的请求,因为此方法会多次调用。如果您想避免额外的头痛,请为此使用任何库。
  • 好的,但是为什么需要TextView 中的图像?请提及您的要求,因为通常没有人这样做。
  • 如果不这样做,我不知道如何以有组织的方式正确实现 imageView 和 textView。

标签: ios swift uitableview asynchronous swift4


【解决方案1】:

您不应该在后台线程上执行任何 UI 操作。

中删除background.async
        background.async {
                image1Attachment.image = UIImage(data: photoUploadData!)
        }

简单地使用

image1Attachment.image = UIImage(data: photoUploadData!)

编辑:

延迟不是因为UIImage(data: photoUploadData!) 我同意这是一个同步调用,但不会造成延迟真正的罪魁祸首是let image1String = NSAttributedString(attachment: image1Attachment) NSAttributedString 众所周知是臭名昭著的。

要检验假设,您可以注释掉

                let image1String = NSAttributedString(attachment: image1Attachment)


                fullString.append(image1String)
                fullString.append(NSAttributedString(string: messageDisplayString!))

                message2.attributedText = fullString
                message2.textColor = .white
                message2.font = UIFont.systemFont(ofSize: 17.0)

你不应该看到滞后。

不幸的是,我不知道如何解决NSAttributedString 的问题,我们遇到了同样的问题,而且滚动大量行时经常会出现延迟。因此我们决定选择DTCoreText

不知何故,这比NSAttributedString表现得更好

编辑:

我们得出的结论是,延迟/滞后可能是由于将大量数据转换为NSAttributedString。由于 OP 想要做的只是在其下方显示图像和文本,因此他不知道如何处理单元格中的多个组件,因此我将答案更新为相同。

我并不是说这是这样做的唯一方法可能有助于 OP 在这里假设

第一步:

创建 UITableViewCell xib 并将 UIImageView 拖到其中。

现在 imageViews 可以采用隐式大小。这意味着 UIImageView 可以根据图像显示增长。如果您正在加载的图像恰好在您的控制之下(服务器发送图像是您的),并且如果您的后端团队可以确保他们不会发送疯狂的大图像,那么您不需要对 ImageView 进行高度限制。

但通常情况下,服务器团队声称它是客户端团队的工作。因为您想以最佳方式显示图像并显示具有宽高比的图像,并让图像的较大部分被切掉,或者如果图像恰好很小,在图像周围留下巨大的空间,请后端团队将宽高比作为部分响应。

所以在这种情况下,为 imageView 创建一个高度约束

为高度约束创建一个 IBOutlet 假设您将其称为 imageHeightConstraint

现在,当您在单元格中加载图像时,您知道 imageView 的宽度将等于单元格的宽度,并且您知道要显示的图像的纵横比,因此您可以计算假定图像的高度为

cellFroRowAtIndexPath

cell.imageHeightConstraint.constant = cell.bounds.size.width * aspectRatioOfImage

或者如果你在一个单元格中有configure 方法,你希望单元格配置它的子视图那么更好

self.imageHeightConstraint.constant = self.bounds.size.width * aspectRatioOfImage

显然,您可能需要将其从 CGFloat 转换为 Float,我相信您可以做到 :)

现在,如果您对图像没有任何控制权,并且您从某个随机网站下载它,因此没有纵横比信息,那么与其添加高度约束,不如向 imageView 添加纵横比约束并将 imageView 内容模式更改为 .aspectFit 这可能有我上面提到的副作用,但在没有任何支持的情况下,这是最好的 :)

现在在 imageView 下面添加 TextView

在imageView和TextView之间添加垂直高度约束

选择 textView 并将启用滚动设置为 false

选择 TextView 并将垂直内容拥抱优先级和压缩阻力更改为 999

就是这样:)

现在,您通过所有这些马戏团取得的成就是,现在您拥有了一个 TableViewCell,它可以根据它所拥有的内容采用隐式大小,而不会产生任何歧义 :)

现在这让生活变得轻松。实现 tableView 委托,不要忘记使用

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;

就是这样 :) 现在运行您的代码并根据它们显示的内容享受自我扩展的 tableView 单元格:) 您拥有您想要的布局

希望对你有帮助

【讨论】:

  • 我首先引入异步的原因是因为滞后。无论有没有异步,它都会滞后。
  • @husharoonie : 延迟不是因为UIImage(data: photoUploadData!) 我同意这是一个同步调用但不会造成延迟真正的罪魁祸首是let image1String = NSAttributedString(attachment: image1Attachment) NSAttributedString 是众所周知的臭名昭著
  • 如何更改?当它接触索引而不是加载实际图像时,它更像是一个小故障。
  • @husharoonie :阅读更新的答案,让我知道它是否有帮助
  • 图像通过文本视图显示。我需要没有它图像不会显示的那部分。
猜你喜欢
  • 1970-01-01
  • 2018-07-03
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多