CollectionView 索引更改时更新分段进度条 Swift

Update Segmented Progress Bar When CollectionView Index is Changed Swift

Working Example Video

我正在尝试创建一个入门视图,例如在视图顶部带有进度条的 Instagram 故事。

到目前为止,我已经能够在给定时间内对第二个或第三个索引进行动画处理。此动画还会更改堆栈视图进度条。但是当我尝试滚动到下一个或上一个集合视图索引时,我无法在进度条内显示此操作。

我可以使用页面控件读取当前页面索引,但无法将此读取反映到进度条。

class OnboardingViewController: UIViewController, SegmentedProgressBarDelegate {
    
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var stackView: UIStackView!
    
    private var spb: SegmentedProgressBar!
    
    var currentPage = 0
    
    lazy var pageControl: UIPageControl = {
        let pageControl = UIPageControl()
        pageControl.numberOfPages = slides.count
        return pageControl
    }()
    
    //Burası Presenter'dan gelecek.
    var slides: [OnboardingSlide] = [
        OnboardingSlide(title: "Delicious Dishes", image: #imageLiteral(resourceName: "1")),
        OnboardingSlide(title: "World-Class Chefs", image: #imageLiteral(resourceName: "2")),
        OnboardingSlide(title: "Instant World-Wide Delivery", image: #imageLiteral(resourceName: "3"))
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        spb = SegmentedProgressBar(numberOfSegments: slides.count, duration: 3)
        spb.frame = CGRect(x: 15, y: 56, width: collectionView.frame.width - 30, height: 4)
        spb.delegate = self
        spb.topColor = UIColor.white
        spb.bottomColor = UIColor.white.withAlphaComponent(0.25)
        spb.padding = 2
        collectionView.delegate = self
        collectionView.dataSource = self
        stackView.addArrangedSubview(spb)
        spb.startAnimation()
        collectionView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tappedView)))
    }
    
    func segmentedProgressBarChangedIndex(index: Int) {
        updateView(index: index)
    }
    
    override var prefersStatusBarHidden: Bool {
        return true
    }
    
    func segmentedProgressBarFinished() {
        print("Finished!")
    }
    
    @objc private func tappedView() {
        spb.isPaused = !spb.isPaused
    }
    
    private func updateView(index: Int) {
        print("index: \(index)")
        let indexPath = IndexPath(row: index, section: 0)
        collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
    }
   
    @IBAction func loginButtonTapped(_ sender: UIButton) {
    }
    
    @IBAction func signupButtonTapped(_ sender: UIButton) {
    }
    
}

extension OnboardingViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return slides.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: OnboardingCollectionViewCell.identifier, for: indexPath) as! OnboardingCollectionViewCell
        cell.setup(slides[indexPath.row])
        return cell
    }
    
    
}

extension OnboardingViewController: UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let width = scrollView.frame.width
        currentPage = Int(scrollView.contentOffset.x / width)
        pageControl.currentPage = currentPage
        updateView(index: currentPage)
        print("current page: \(currentPage)")
    }
}

我用过 https://github.com/D-32/SegmentedProgressBar

作为分段进度条

class OnboardingCollectionViewCell: UICollectionViewCell {
    
    static let identifier = String(describing: OnboardingCollectionViewCell.self)
    
    @IBOutlet weak var slideImageView: UIImageView!
    @IBOutlet weak var slideTitleLabel: UILabel!
    
    func setup(_ slide: OnboardingSlide) {
        slideImageView.image = slide.image
        slideTitleLabel.text = slide.title
    }
}

struct OnboardingSlide {
    let title: String
    let image: UIImage
}
extension OnboardingViewController: UICollectionViewDelegateFlowLayout {
    
    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        if scrollView.panGestureRecognizer .translation(in: view).x > 0 {
            spb.rewind()
            } else {
                spb.skip()
            }
    }
}

有了这个,我能够理解集合视图是向左滚动还是向右滚动。因此在 spb 中调用相关函数就可以了。