โหลดรูปภาพใน Table View แบบ Lazy Loading (โหลดเฉพาะที่เห็น) ด้วย URLSession และ Extension
ขั้นตอนหลัก
- สร้าง Table View, Cell, Image View
- สร้าง Custom Cell Class
- ใช้ URLSession ดาวน์โหลดรูปแบบ Async
- Cache รูปภาพเพื่อไม่โหลดซ้ำ
Extension UIImageView สำหรับโหลดรูป
extension UIImageView {
func setImage(from urlString: String, placeholder: UIImage? = nil) {
self.image = placeholder
guard let url = URL(string: urlString) else { return }
// ตรวจสอบ Cache ก่อน (ใช้ NSCache หรือ Library)
if let cached = ImageCache.shared.image(forKey: urlString) {
self.image = cached
return
}
URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
guard let self = self,
let data = data,
let image = UIImage(data: data),
error == nil else { return }
// Cache รูป
ImageCache.shared.setImage(image, forKey: urlString)
DispatchQueue.main.async {
// ตรวจสอบว่า Cell ยังแสดงอยู่ (ป้องกันการแสดงรูปผิด Cell)
if self.image == placeholder || self.image == nil {
self.image = image
}
}
}.resume()
}
}
Simple Image Cache
class ImageCache {
static let shared = ImageCache()
private let cache = NSCache()
private init() {}
func image(forKey key: String) -> UIImage? {
return cache.object(forKey: key as NSString)
}
func setImage(_ image: UIImage, forKey key: String) {
cache.setObject(image, forKey: key as NSString)
}
}
การใช้งานใน Cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
let url = imageURLs[indexPath.row]
cell.imageView.setImage(from: url, placeholder: UIImage(named: "placeholder"))
return cell
}
แนะนำ: ใช้ Library
สำหรับ Production ควรใช้ Library ที่มATURE แล้ว:
- Kingfisher - Swift, รองรับ Cache, Progress, Processor
- SDWebImage - Objective-C/Swift, มาตรฐานอุตสาหกรรม
- Nuke - Swift, ประสิทธิภาพสูง, Pipeline ยืดหยุ่น
ตัวอย่าง Kingfisher:
import Kingfisher
imageView.kf.setImage(with: URL(string: url), placeholder: UIImage(named: "placeholder"))