bugfix> ios > 投稿

画像またはテキストを表示するUITableViewCellがあります。 UIImageViewの高さと幅を<= 150に設定したので、画像は表示されていなくてもテキストは表示されている場合にセルの高さに影響を与えません。 (これはメッセージングアプリです)

今私の問題は、セルが読み込まれた後にセルが表示されず、ユーザーが戻って画像を表示するためにこの画面を再度表示する必要があることです。これをどのように解決すればよいですか?

画像がロードされる前:

イメージが正常にロードされた後:

あなたが見ることができるように、それは表示されません、ビューのみが展開されました

ユーザーが[戻る]を押してこのビューに再びアクセスすると、

画像が表示されます。

この問題を解決するにはどうすればよいですか?私は tableview.reloaddata() を書くことができないのでtableviewcellで。

tableviewcellのコードでセルを構成するには:

func configCell(message: Message) {
    self.message = message
    if message.fromId == currentUser {
        sentView.isHidden = false
        sentMsgLabel.text = message.textMessages
        receivedMsgLabel.text = ""
        receivedView.isHidden = true
        timeReceived.text = ""
        timeSent.text = message.timestamp
        youLabel.text = "You"
        themLabel.text = ""

        if let ImageUrl = message.imageUrlLink {
            self.receivedimg.loadImageUsingCacheWithUrlString(ImageUrl)
        }
        }
        else {
        sentView.isHidden = true
        sentMsgLabel.text = ""
        receivedMsgLabel.text = message.textMessages
        receivedMsgLabel.isHidden = false
        timeReceived.text = message.timestamp
        timeSent.text = ""
        // setting name for receipient
        Database.database().reference().child("users").child(message.fromId!).child("name").observe(.value) { (datasnapshot) in
        if let name = datasnapshot.value as? String {
                self.themLabel.text = name
            }
        }
        youLabel.text = ""
    }
}

私のloadImageUsingCacheWithUrlStringコードの場合、次のような拡張機能になります。

let imageCache = NSCache<AnyObject, AnyObject>()
    extension UIImageView {
    func loadImageUsingCacheWithUrlString(_ urlString: String) {
        self.image = nil
        //check cache for image first
        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = cachedImage
            return
        }
        //otherwise fire off a new download
        let url = URL(string: urlString)
        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
            //download hit an error so lets return out
            if error != nil {
                print(error ?? "")
                return
            }
            DispatchQueue.main.async(execute: {
                if let downloadedImage = UIImage(data: data!) {
                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                    self.image = downloadedImage
                }
            })
        }).resume()
    }
}

回答 4 件
  • 画像をダウンロードした後、あなたの問題は明らかに、あなたのセルはすぐに更新されません、試してくださいself.setNeedDisplays() あなたの細胞の中。次の表示サイクルでセルを更新する必要があることを示します。

    自分自身をロードしてキャッチする代わりに、KingFisherフレームワークを使用することをお勧めします。リモートサーバーからのイメージの操作に必要なほぼすべてを実行します。ダウンロード後すぐに画像を表示する

  • 最終的には非常に多くの方法を試しました.ViewDidloadで、遅延を追加しました

    DispatchQueue.main.asyncAfter(deadline: .now() + 1){
            self.tableView.reloadData()
        }
    
    

    遅延が必要です。それなしでは機能しません。画像の読み込みが完了する前にセルの高さが設定されて読み込まれたため、テーブルセルは必要な高さを認識していなかったため、1秒後にTableViewを再読み込みする必要があります

  • UITableViewCell にアクションを実行する代わりに   cellForRowAt 内でアクションを実行する

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //Your actuions here
    }
    
    

    その後、 tableView.reloadData() を使用できます  あなたの UITableViewController の中

    これが問題の解決に役立つことを願っています。

  • このコードは1回実行されているようですが、カウントが明らかに2であるため、UITableViewはまだセルをロードしています。Messageオブジェクトを UICollectionViewCell に渡すと   cellForRowAt indexPath 内のクラス  メソッド、あなたは didSet を使用したいと思うでしょう  そのメッセージで、関数を呼び出します。これは、メッセージが渡されるたびに、また渡されるときに、didSet内にあるものがすべて実行されることを意味します。

    UICollectionViewCellクラス内:

    var message: Message? {
        didSet {
            configCell(message)
        }
    }
    
    

    UITableViewControllerを持つクラス:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = // your cell here dequeue cell and downcast as your cell class e.g as! MyCell
        cell.message = yourMessagesArray[indexPath.row]
        return cell
    }
    
    

あなたの答え