iOS UITableViewCell自动布局不刷新:图片显示异常求助
问题:UITableViewCell中图片初始显示为正方形,滚动后才适配正确高度
我在制作帖子列表布局,已通过独立ImageCell.xib完成图文布局设计,并在viewDidLoad()中完成Cell注册。当前内容可完整显示,但存在布局渲染问题:上传矩形图片时,列表中该图片初始显示为正方形,仅在滚动后对应的ImageCell才会适配完整高度。
相关代码片段
ImageCell类
class ImageCell: UITableViewCell { //MARK: - Properties @IBOutlet weak var lblUserName: NBLabel! @IBOutlet weak var imgProfile: UIImageView! { didSet{ imgProfile.layer.cornerRadius = imgProfile.frame.size.height / 2 imgProfile.clipsToBounds = true } } @IBOutlet weak var imgFeedBG: ScaledHeightImageView! static let identifier = "ImageCell" override func awakeFromNib() { super.awakeFromNib() } override func layoutSubviews() { super.layoutSubviews() DispatchQueue.main.asyncAfter(deadline: .now()) { if self.imgFeedBG != nil { self.imgFeedBG.contentMode = .scaleAspectFill } self.setNeedsLayout() self.needsUpdateConstraints() self.setNeedsDisplay() self.layoutIfNeeded() } } override func prepareForReuse() { self.lblDesc.text = nil self.imgFeedBG.image = nil super.prepareForReuse() } func setupWithItem(_ dict: PostElement) { let feedImageUrl = dict.imageURL.replacingOccurrences(of: " ", with: "%20") self.imgFeedBG.sd_imageIndicator = SDWebImageActivityIndicator.whiteLarge } }
PostVC类
class PostVC: UIViewController { @IBOutlet weak var tableViewPosts: UITableView! var arrData = [PostElement]() override func viewDidLoad() { super.viewDidLoad() self.tableViewPosts.estimatedSectionHeaderHeight = 0 self.tableViewPosts.estimatedSectionFooterHeight = 0 tableViewPosts?.register(UINib(nibName: ImageCell.identifier, bundle: nil), forCellReuseIdentifier: ImageCell.identifier) self.tableViewPosts.delegate = self self.tableViewPosts.dataSource = self } override func viewDidAppear(_ animated : Bool) { super.viewDidAppear(animated) /* DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: { self.tableViewPosts.beginUpdates() self.tableViewPosts.setNeedsDisplay() self.tableViewPosts.endUpdates() }) */ UIView.performWithoutAnimation { self.tableViewPosts.beginUpdates() self.tableViewPosts.reloadData() self.tableViewPosts.endUpdates() } } } extension PostVC : UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let dict = arrData[indexPath.row] guard let cell = tableView.dequeueReusableCell(withIdentifier: ImageCell.identifier) as? ImageCell else {return UITableViewCell()} cell.setupWithItem(dict) DispatchQueue.main.async { UIView.performWithoutAnimation { cell.setNeedsLayout() cell.layoutIfNeeded() } } return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension } func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return 100 // UITableView.automaticDimension } }
补充说明:
- 已参考Xib设计图确认布局约束设置
- 当前错误效果:矩形图片初始显示为正方形,滚动Cell出屏再返回后高度恢复正常
解决方案
1. 完善ScaledHeightImageView的自适应逻辑
确保自定义图片视图能根据图片宽高比自动计算高度,并在图片加载完成后触发布局更新:
class ScaledHeightImageView: UIImageView { override var image: UIImage? { didSet { invalidateIntrinsicContentSize() superview?.setNeedsLayout() superview?.layoutIfNeeded() } } override var intrinsicContentSize: CGSize { guard let image = image else { return super.intrinsicContentSize } let width = bounds.width let height = (image.size.height / image.size.width) * width return CGSize(width: width, height: height) } }
2. 清理ImageCell中冗余的布局代码
删除layoutSubviews里的异步操作,避免打乱布局更新时机:
override func layoutSubviews() { super.layoutSubviews() if imgFeedBG != nil { imgFeedBG.contentMode = .scaleAspectFill } }
3. 图片加载完成后触发Cell高度更新
修改ImageCell的setupWithItem方法,利用SDWebImage的回调通知TableView更新对应Cell高度:
func setupWithItem(_ dict: PostElement) { let feedImageUrl = dict.imageURL.replacingOccurrences(of: " ", with: "%20") self.imgFeedBG.sd_imageIndicator = SDWebImageActivityIndicator.whiteLarge // 图片加载完成后刷新Cell高度 self.imgFeedBG.sd_setImage(with: URL(string: feedImageUrl)) { [weak self] _, _, _, _ in guard let self = self, let tableView = self.superview as? UITableView, let indexPath = tableView.indexPath(for: self) else { return } tableView.performBatchUpdates({ tableView.reloadRows(at: [indexPath], with: .none) }, completion: nil) } }
4. 优化TableView的高度估算与刷新逻辑
- 将
estimatedHeightForRowAt设置为更接近实际的数值,或直接使用UITableView.automaticDimension - 删除
viewDidAppear中冗余的TableView刷新代码,避免不必要的布局抖动
5. 验证Xib约束正确性
检查ImageCell.xib:
imgFeedBG需设置左右边距、顶部间距约束,不要设置固定高度- Cell的底部约束必须连接到
imgFeedBG的底部,确保TableView能正确计算自动高度
内容的提问来源于stack exchange,提问作者Keval Gajjar
相关产品推荐
相关产品推荐

