为什么函数heightForRowAt总是找到包含行高的数组,即使重新加载行后,该行高最初设置为nil仍为nil。

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Reuse", for: indexPath) as! TableViewCell

    let downloadURL = URL(string: self.imageURLS[indexPath.row])


    if cell.cellImageView.image == nil{
        URLSession.shared.dataTask(with: downloadURL!) { (data, _, _) in
            if let data = data {
                let image = UIImage(data: data)
                DispatchQueue.main.async {
                    cell.setCellImage(image:image!)
                    self.rowHeights?.insert((cell.imageView?.frame.height)!, at: indexPath.row)
                    tableView.reloadRows(at: [indexPath], with: .top)
                }
            }
            }.resume()
    }
    return cell
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let rowHeights = self.rowHeights else{
        print("returned nil")
        return 500.0
    }
    print("the array exists at \(indexPath.row) with value: \(rowHeights[indexPath.row])")
    return rowHeights[indexPath.row]
}
}


更新的TableViewController

import UIKit
import Firebase
import FirebaseStorageUI

class TableViewController: UITableViewController {
var images:[UIImage]! = [#imageLiteral(resourceName: "rininger_2.jpg")]
var imageURLS:[String] = [String]()
var rowHeights:[CGFloat] = [CGFloat]()
var listener:ListenerRegistration?

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
    listener = Firestore.firestore().collection("Posts").addSnapshotListener{
        querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error fetching snapshots: \(error!)")
            return
        }
        snapshot.documentChanges.forEach { diff in
            if (diff.type == .added) {
                print("New data: \(diff.document.data())")
            }
            if (diff.type == .modified) {
                print("Modified data: \(diff.document.data())")
            }
            if (diff.type == .removed) {
                print("Removed data: \(diff.document.data())")
            }

            guard let newImageURL = diff.document.data()["imageDownloadURL"] as? String else{
                print("Failed to get image download URL")
                return
            }
            print("downloadURL: \(newImageURL)")
            self.imageURLS.insert(newImageURL, at: 0)
            let indexPath = IndexPath(row: 0, section: 0)
            self.tableView.insertRows(at: [indexPath], with: .top)


        }

    }
    tableView.estimatedRowHeight = 100.0
    tableView.rowHeight = UITableViewAutomaticDimension
}


override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return imageURLS.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Reuse", for: indexPath) as! TableViewCell

    let downloadURL = URL(string: self.imageURLS[indexPath.row])


    if cell.cellImageView.image == nil{
        URLSession.shared.dataTask(with: downloadURL!) { (data, _, _) in
            if let data = data {
                let image = UIImage(data: data)
                self.images.insert(image, at: indexPath.row)
                DispatchQueue.main.async {
                    cell.setCellImage(image:image!)
                   // self.rowHeights.insert((cell.imageView?.frame.height)!, at: indexPath.row)
                   //tableView.reloadData()
                   tableView.reloadRows(at: [indexPath], with: .top)
                }
            }
            }.resume()
    }
    return cell
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    print("UITableViewAutomaticDimension: \(UITableViewAutomaticDimension)")
    return UITableViewAutomaticDimension
}


}

最佳答案

您的代码中有很多问题

1-首先您必须下载,保存图像,然后重新加载表格

2秒内,您应该使用自动表格视图高度来完成此操作,而不要像当前所做的那样使用高度数组

解决1

   NSString *getImagePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.jpeg",n1.Id]];

    if([[NSFileManager defaultManager] fileExistsAtPath:getImagePath])
    {
        UIImage *img = [UIImage imageWithContentsOfFile:getImagePath];
        cell.leftImageV.image =img;
        [cell.activity stopAnimating];
        cell.activity.hidden=YES;
    }
    else
    {

        [cell.activity startAnimating];
         cell.activity.hidden=NO;

        cell.leftImageV.image = nil;

        NSLog(@"xdasdxsadxa %@",n1.mainImgStr);

        dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        dispatch_async(concurrentQueue, ^{
            __block NSData * imageData  = nil;
            dispatch_sync(concurrentQueue, ^{

                imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:n1.mainImgStr]];

                //Add the file name
                [imageData writeToFile:getImagePath atomically:YES]; //Write the file

            });

            dispatch_sync(dispatch_get_main_queue(), ^{

                if(imageData)
                {
                    [self.tableView reloadData];

                }
            });
        });


解决2

要为行高和估计的行高设置自动尺寸,请确保执行以下步骤,自动尺寸对单元格/行高的布局有效。我只测试了以下步骤和代码,即可正常工作。


分配并实现tableview数据源和委托
UITableViewAutomaticDimension分配给rowHeight和估计的RowHeight
实现委托/数据源方法(即heightForRowAt并向其返回值UITableViewAutomaticDimension


--

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension
}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

关于ios - 为什么在调用reloadRows之后,heightForRowAt没有在数组中找到值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48268529/

10-12 00:41
查看更多