UITableView 是 iOS 開發中最經常使用的控件之一,使用 UITaleView 時最頭疼的莫過於 cell 高度的計算,雖然說在 iOS8.0 之後引入了自適應方法,但在適配過程當中任然會遇到各類難題,尤爲是爲了知足產品需求進行復雜 cell 自定義時,高度計算可謂是難上加難.這裏主要對開發中遇到的自定義 cell 是加載網絡圖片適配問題進行總結.git
在開發中爲了用戶能有更好體驗,對網絡請求多采用異步請求的方式,更有甚者對請求數據作了本地緩存.圖片做爲 app 中最多見的展示形式無疑是最耗流量的,對圖片的處理直接影響到用戶的體驗,好在有大神爲咱們提供了好的框架(Kingfisher,SDWebImage),大大提升了咱們的開發效率.github
圖片的異步加載提升了用戶體驗,卻在開發中遇到了新的難題,由於圖片異步加載你沒法提早預知圖片的尺寸,在佈局時難以控制 UIImageView 的大小,若是將 UIImageView 固定大小勢必會形成圖片的壓縮或拉伸,如今主要針對於自定義 cell 時對圖片自適應佈局提一些建議.swift
在開發中咱們時常會將 UIImageView 固定大小或者固定寬高比例,經過設置 ImageView 的 contentMode 屬性設置圖片的顯示風格.
該方法簡單容易形成圖片壓縮拉伸或顯示不全問題.
contentMode 取值:緩存
public enum UIViewContentMode : Int {
case scaleToFill //縮放內容到合適比例大小
case scaleAspectFit //縮放內容到合適的大小,邊界多餘部分透明
case scaleAspectFill //縮放內容填充到指定大小,邊界多餘的部分省略
case redraw //重繪視圖邊界
case center //視圖保持等比縮放,居中
case top //視圖頂部對齊
case bottom //視圖底部對齊
case left //視圖左側對齊
case right //視圖右側對齊
case topLeft //視圖左上角對齊
case topRight //視圖右上角對齊
case bottomLeft //視圖左下角對齊
case bottomRight //視圖右下角對齊
}
複製代碼
在上傳圖片時能夠將圖片的大小一塊兒上傳服務器保存,在用戶加載圖片時將圖片信息和圖片 URL 地址一塊兒返回,根據返回的圖片信息計算 UIImageView 的 size 進行佈局.
該方法比較簡單,但須要後臺配合使用.服務器
不管 SDWebiamge 仍是 Kingfisher,做者都給咱們提供了圖片加載完回調方法,咱們能夠在圖片加載完後從新計算 cell 高度.
該方法大大加大了 cell 的刷新頻率.
具體步驟:網絡
var refreshCell: ((IndexPath) -> Void)?
iconImageView.kf.setImage(with: URL(string: iconImageURL), placeholder: UIImage(named: "tmp")) { [weak self](image, error, type, url) in
if type == .none {
self?.iconImageView.image = self?.iconImageView.image?.ytt.resetImageSizeWithWidth(UIScreen.main.bounds.width)
ImageCache.default.store((image?.ytt.resetImageSizeWithWidth(UIScreen.main.bounds.width))!, forKey: (url?.absoluteString)!)
self?.refreshCell?(indexPath)
}
}
複製代碼
cell.refreshCell = {(index) in
if (tableView.indexPathsForVisibleRows?.contains(index))! {
tableView.reloadRows(at: [index], with: .automatic)
}
}
複製代碼
在給 UIImageView 賦值時經過 ImageIO 獲取 image 的尺寸,修改 UIImageView 的大小.
該方法須要在網絡請求數據,加大了數據請求量.
實現代碼:閉包
let imageSource = CGImageSourceCreateWithURL(URL(string: iconImageURL)! as CFURL, nil)
if let result = CGImageSourceCopyPropertiesAtIndex(imageSource!, 0, nil) as? Dictionary<String, Any> {
if let width = result["PixelWidth"] as? CGFloat, let height = result["PixelHeight"] as? CGFloat {
let h = (UIScreen.main.bounds.width - 20) / (width / height)
iconImageView.snp.remakeConstraints { (make) in
make.height.equalTo(h)
}
}
}
複製代碼