Je voulais mettre en œuvre un curseur d'image avec un défilement automatique en utilisant un UIScrollView et un UIStackView. Voici ce que j'ai obtenu et cela fonctionne plutôt bien. J'utilise PureLayout pour AutoLayout :
class ImageSlideShow: UIView {
private let scrollView = UIScrollView()
private var images: [UIImage] = []
private var scrollTimer: Timer?
init() {
super.init(frame: .zero)
self.setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setImages(_ images: [UIImage], initialIndex: Int = 0) {
self.images = images
self.scrollTimer?.invalidate()
self.scrollView.removeAllSubviews()
let stackView = self.getStackView()
self.scrollView.addSubview(stackView)
stackView.autoMatch(.height, to: .height, of: self.scrollView)
stackView.autoPinEdgesToSuperviewEdges()
self.images.forEach { image in
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
stackView.addArrangedSubview(imageView)
imageView.autoMatch(.width, to: .width, of: self.scrollView)
}
self.setupScrollTimer()
}
private func getStackView() -> UIStackView {
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.alignment = .fill
stackView.distribution = .equalSpacing
stackView.spacing = 0
return stackView
}
private func setupScrollTimer() {
self.scrollTimer = Timer.scheduledTimer(
timeInterval: 0.5,
target: self,
selector: #selector(scroll), userInfo: nil,
repeats: true
)
}
@objc private func scroll() {
let currentPage = self.scrollView.contentOffset.x / scrollView.frame.size.width
var nextPage = currentPage + 1
var frame: CGRect = self.scrollView.frame
if nextPage >= CGFloat(self.images.count) {
nextPage = 0
}
frame.origin.x = frame.size.width * CGFloat(nextPage)
self.scrollView.scrollRectToVisible(frame, animated: true)
}
private func setupView() {
self.backgroundColor = Colors.cream
self.setupScrollView()
}
private func setupScrollView() {
self.addSubview(self.scrollView)
self.scrollView.autoPinEdgesToSuperviewEdges(with: .margin(Metrics.paddingDoublePlus))
self.scrollView.isPagingEnabled = true
self.scrollView.layer.cornerRadius = Metrics.cornerRadius
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
}
}