具有较小滞后的TableView单元格(异步正确使用?)Swift

时间:2018-03-21 06:17:39

标签: ios swift uitableview asynchronous swift4

我在 tableView单元格中加载了数组数组。但是我得到了轻微的延迟(更多的故障)当表格视图滚动图像索引时。

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

  

字节数据(624230字节)

     

字节数据(1619677字节)

     

字节数据(2257181字节)

     

字节数据(1120275字节)

不确定如何正确使用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的原因是因为滞后。它有滞后和没有异步。

enter image description here

1 个答案:

答案 0 :(得分: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在这里假设

<强>步骤1:

创建UITableViewCell xib并将UIImageView拖到它。

enter image description here

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

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

因此,在这种情况下,为imageView

创建一个高度约束

enter image description here

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

现在当您在单元格中加载图像时,您知道imageView的宽度将等于单元格的宽度,并且您知道要显示的图像的宽高比,以便您可以计算所需图像的高度

cellFroRowAtIndexPath

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

或更好,如果您在单元格中有configure方法,您希望单元格配置其子视图

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

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

现在,如果您对图像没有任何控制权并且您正在从一些随机网站下载并因此没有宽高比信息,那么而不是添加高度约束添加宽高比约束到imageView并将imageView内容模式更改为.aspectFit这可能有上面提到的副作用,但这是你得到的最好的,没有任何支持:)

enter image description here

现在在imageView

下面添加TextView

enter image description here

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

enter image description here

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

enter image description here

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

enter image description here

多数民众赞成:)

现在你在所有这些马戏团中取得的成就是现在你有一个TableViewCell,它可以根据它拥有的内容采取隐式大小而没有任何歧义:)

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

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

多数民众赞成:)现在运行你的代码并根据他们显示的内容享受自扩展tableView单元格:)你有你想要的布局

希望有所帮助