代码之家  ›  专栏  ›  技术社区  ›  husharoonie

UITableView中的Swift异步调用

  •  0
  • husharoonie  · 技术社区  · 8 年前

    最好的方法是什么 异步调用 加载 UIImage到文本视图 作为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!
    }
    

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

    enter image description here

    2 回复  |  直到 8 年前
        1
  •  0
  •   Cherry_thia    8 年前

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

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

        2
  •  -1
  •   SirCJ    8 年前

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

    首先,没有办法 tableView(:cellForRowAt:) 可以在16毫秒内完成所有工作。我认为你应该重新考虑你的应用程序结构和架构。将网络调用抽象为可以在后台线程上运行的API,这将更好地服务于您的应用程序。

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