Swift implements unlimited rotations
- 2020-05-27 07:17:17
- OfStack
From today on, I will focus on Swift and share some of my own learning experiences. What I will bring to you today is unlimited roving. Unlimited roving of AD pages is a very common feature that most APP have and most programmers have implemented. Today we use Swift to implement 1. The project address
The basic controls we can choose are UIScrollView and UICollectionView. This time we choose UICollectionView. Since it's roving, we'll use Timer. Therefore, the main knowledge points we apply this time are UICollectionView and Timer;
import UIKit
class CycleScrollView: UIView, UICollectionViewDelegate,UICollectionViewDataSource {
var bottomView : UICollectionView?
var width : CGFloat?
var height : CGFloat?
var timer : Timer?
override init(frame: CGRect){
super.init(frame: frame)
// 1. Set the background color
self.backgroundColor = UIColor.clear
// 2. Set the width of high
width = self.frame.size.width
height = self.frame.size.height
// 3. add bottomView
setupBottomView()
// 4. Add timer
setupTimer()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupBottomView() {
// 5. Set up the collectionView The layout of the
let flowLayout = UICollectionViewFlowLayout();
flowLayout.itemSize = self.bounds.size
flowLayout.minimumLineSpacing = 0;
flowLayout.minimumInteritemSpacing = 0;
flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal;
bottomView = UICollectionView.init(frame: self.bounds, collectionViewLayout: flowLayout)
self.addSubview(bottomView!);
// 6. Set up the collectionView The size of the
bottomView?.contentSize = CGSize(width:width! * CGFloat(4),height:height!)
// 7. paging
bottomView?.isPagingEnabled = true
// 8. Get rid of the scroll bar
bottomView?.showsVerticalScrollIndicator = false
bottomView?.showsHorizontalScrollIndicator = false
// 9. Set the agent
bottomView?.delegate = self
bottomView?.dataSource = self
// 10. registered cell
bottomView?.register(UICollectionViewCell().classForCoder, forCellWithReuseIdentifier: "ID");
if #available(iOS 10.0, *) {
// 11. preload
bottomView?.isPrefetchingEnabled = true
} else {
// Fallback on earlier versions
}
}
func setupTimer() {
// 12. Instantiate the timer
timer = Timer.init(timeInterval: 2, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true);
RunLoop.main.add(timer!, forMode: RunLoopMode.defaultRunLoopMode);
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.timer?.fire();
}
}
func timerAction() {
var contentOffsetX = (self.bottomView?.contentOffset.x)! + self.frame.size.width
if contentOffsetX > self.frame.size.width * 3 {
// The current view shows no 3 Set the bottomView The offset is zero 0
self.bottomView?.contentOffset = CGPoint(x:0,y:0)
contentOffsetX = self.frame.size.width
}
self.bottomView?.setContentOffset(CGPoint(x:contentOffsetX,y:0), animated: true)
}
// rewrite removeFromSuperview Method used to delete the timer, otherwise the timer 1 Direct presence, wasted memory
override func removeFromSuperview() {
timer?.invalidate()
timer = nil
super.removeFromSuperview()
}
// Mark:UICollectionViewDataSource
// Set up the Itmes
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4;
}
// Set up the cell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ID", for: indexPath)
for view : UIView in cell.contentView.subviews {
view.removeFromSuperview()
}
let imageView = UIImageView.init(frame: cell.contentView.bounds)
if indexPath.row < 3 {
imageView.image = UIImage.init(named: String(indexPath.row))
} else {
imageView.image = UIImage.init(named: String(0))
}
cell.contentView.addSubview(imageView)
return cell;
}
// Mark:UICollectionViewDelegate
// Click on the way
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(" You click the first \(indexPath.row == 3 ? 0 : indexPath.row) a ");
}
}
The usage of UICollectionView and Timer is basically the same as that of OC. The UI part of Swift and OC should be 1 to 1, because the bottom layer is OpenGL. Let me just say one difference:
1.Timer: if repeated, OC is executed at an interval; Swift is executed immediately, so I used GCD to start the timer delayed.
2.Swift has no CGPointZero.
The principle of infinite roving is to add the same itme as the first one at the end. When you slide to the last itme, set contentOffset of UICollectionView to zero and continue to move to the right. If it is not added, it will give the user a feeling of being stuck.