107 lines
3.1 KiB
Swift
107 lines
3.1 KiB
Swift
import UIKit
|
|
|
|
class GIFCollectionViewCell: UICollectionViewCell {
|
|
|
|
private let gifPlayerView: GIFPlayerView = {
|
|
let player = GIFPlayerView()
|
|
player.layer.cornerRadius = 8
|
|
player.clipsToBounds = true
|
|
return player
|
|
}()
|
|
|
|
private let loadingIndicator: UIActivityIndicatorView = {
|
|
let indicator = UIActivityIndicatorView(style: .medium)
|
|
indicator.hidesWhenStopped = true
|
|
return indicator
|
|
}()
|
|
|
|
private let placeholderLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.text = "GIF"
|
|
label.textAlignment = .center
|
|
label.font = .systemFont(ofSize: 12, weight: .medium)
|
|
label.textColor = .systemGray
|
|
return label
|
|
}()
|
|
|
|
private var currentTask: URLSessionDataTask?
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
setupUI()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
setupUI()
|
|
}
|
|
|
|
override func prepareForReuse() {
|
|
super.prepareForReuse()
|
|
currentTask?.cancel()
|
|
currentTask = nil
|
|
gifPlayerView.stopAnimating()
|
|
placeholderLabel.isHidden = false
|
|
loadingIndicator.stopAnimating()
|
|
}
|
|
|
|
private func setupUI() {
|
|
contentView.addSubview(gifPlayerView)
|
|
contentView.addSubview(loadingIndicator)
|
|
contentView.addSubview(placeholderLabel)
|
|
|
|
gifPlayerView.translatesAutoresizingMaskIntoConstraints = false
|
|
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
|
|
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
NSLayoutConstraint.activate([
|
|
gifPlayerView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
|
gifPlayerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
|
gifPlayerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
|
gifPlayerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
|
|
|
loadingIndicator.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
|
loadingIndicator.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
|
|
|
placeholderLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
|
placeholderLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
|
])
|
|
|
|
contentView.layer.cornerRadius = 8
|
|
contentView.layer.borderWidth = 1
|
|
contentView.layer.borderColor = UIColor.systemGray4.cgColor
|
|
}
|
|
|
|
func configure(with urlString: String) {
|
|
// Cancel any existing task
|
|
currentTask?.cancel()
|
|
|
|
// Reset UI
|
|
gifPlayerView.stopAnimating()
|
|
placeholderLabel.isHidden = false
|
|
loadingIndicator.startAnimating()
|
|
|
|
guard let url = URL(string: urlString) else {
|
|
loadingIndicator.stopAnimating()
|
|
return
|
|
}
|
|
|
|
// Load the GIF
|
|
currentTask = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
|
|
DispatchQueue.main.async {
|
|
guard let self = self else { return }
|
|
self.loadingIndicator.stopAnimating()
|
|
|
|
if let data = data, error == nil {
|
|
self.gifPlayerView.loadGIF(from: data)
|
|
self.gifPlayerView.startAnimating()
|
|
self.placeholderLabel.isHidden = true
|
|
} else {
|
|
self.placeholderLabel.isHidden = false
|
|
}
|
|
}
|
|
}
|
|
|
|
currentTask?.resume()
|
|
}
|
|
} |