【问题标题】:Swift Async Call in UITableViewUITableView 中的 Swift 异步调用
【发布时间】:2018-03-20 02:51:57
【问题描述】:

异步调用UIImage 加载到 textView 作为 tableView 中的 NSTextAttachment 的最佳方法是什么?到目前为止,这工作非常糟糕。

我正在使用 URL 字符串在多个 tableView 单元格中加载单个图像。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell")

    //Transform Data From ^ to load at the bottom
    tableView.transform = CGAffineTransform (scaleX: 1,y: -1);
    cell?.contentView.transform = CGAffineTransform (scaleX: 1,y: -1);
    cell?.accessoryView?.transform = CGAffineTransform (scaleX: 1,y: -1);

    let username = cell?.viewWithTag(1) as! UITextView
    username.text = messageArray[indexPath.row].username

    let message = cell?.viewWithTag(2) as! UITextView
    //message.text = messageArray[indexPath.row].message // delete later

    var test = messageArray[indexPath.row].uploadedPhotoUrl
    print(test ?? String.self)

    if(test != ""){
        // create an NSMutableAttributedString that we'll append everything to
        let fullString = NSMutableAttributedString(string: "")

        // create our NSTextAttachment
        let image1Attachment = NSTextAttachment()

        URLSession.shared.dataTask(with: NSURL(string: messageArray[indexPath.row].uploadedPhotoUrl)! as URL, completionHandler: { (data, response, error) -> Void in
            if error != nil {
                print(error ?? String())
                return
            }

            DispatchQueue.main.async(execute: { () -> Void in
                let image = UIImage(data: data!)
                image1Attachment.image = image

                //calculate new size.  (-20 because I want to have a litle space on the right of picture)
                let newImageWidth = (message.bounds.size.width - 20 )

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

                // wrap the attachment in its own attributed string so we can append it
                let image1String = NSAttributedString(attachment: image1Attachment)

                // add the NSTextAttachment wrapper to our full string, then add some more text.
                fullString.append(image1String)
                fullString.append(NSAttributedString(string: message.text))

                // draw the result in a label
                message.attributedText = fullString

                //message.textStorage.insert(image1String, at: message.selectedRange.location)

                message.textColor = .white

                test = ""
            })
        }).resume()
    }else {
        message.text = messageArray[indexPath.row].message
    }

    let timeStamp = cell?.viewWithTag(3) as! UILabel
    timeStamp.text = messageArray[indexPath.row].timeStamp

    let imageView = cell?.viewWithTag(4) as! UIImageView
    imageView.image = nil
    let urlString = messageArray[indexPath.row].photoUrl
    imageView.layer.cornerRadius = 10
    imageView.clipsToBounds = true

    //Load profile image(on cell) with URL & Alamofire Library
    let downloadURL = NSURL(string: urlString!)
    imageView.af_setImage(withURL: downloadURL! as URL)

    return cell!
}

当索引滚动时图像仍然滞后(出现和消失)并且也没有完全加载

【问题讨论】:

  • 考虑到您的cellForRowAt 中没有表格视图单元格的代码,难怪它不起作用。
  • 我没有发布我想要完成的整个问题
  • “工作不佳”不是一个有用的描述。请edit您的问题,详细说明您在发布代码时遇到的确切问题。
  • 我已经更新了。
  • 这很慢,因为您在加载 tableview 时一次调用每个图像。

标签: ios swift asynchronous uitextview


【解决方案1】:

当 tableviewcell 滚动时,您一次加载图像。有一段时间调用服务然后等待返回响应,从而影响滚动虽然它在另一个线程上。

您可以尝试一次调用 10 或 20 个图像。

【讨论】:

  • 如何批量调用?
【解决方案2】:

TL/DR: 学习编写更好的代码。

对于初学者来说,tableView(:cellForRowAt:) 不可能在 16 毫秒内完成所有工作。我认为您应该为初学者重新考虑您的应用程序结构和架构。将网络调用抽象到可以在后台线程上运行的 API 会更好地为您的应用程序服务。

一种方法是将大量实现抽象到OperationQueue Ray Wenderlich 有几个关于如何工作的教程。这个特别的是为 Swift 1.2 编写的,但是 Operation 的原则在那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    相关资源
    最近更新 更多