iOS那些“垃圾”的輪播

KarSVO 8年前發布 | 6K 次閱讀 iOS開發 移動開發

輪播視圖通常也叫Banner,90%以上App都會用到的一個控件,網上有很多開源代碼,但是至今我覺得比較好的一個是 SDCycleScrollView ,因為他解決了我接下來要吐槽的兩個問題。

通常實現定時自動滾動Banner的思路大體有三種

1.  3個`UIImageView`
  2.  N+2個`UIImageView`思路
  3.  N * section(個人不推薦,因為這將代碼寫死了,當有個無聊的人真的滾動到最后一個section時,程序就會crash了)

前兩種思路又分為用 UIScrollView 和 UICollectionView 實現, 個人沒有用過第一種思路,都是第二種,本文也是基于第二種思路 ,這兩種思路的中心思想其實都是運用了 視覺誤差

快速滑動時卡頓

先來看看那些“垃圾”Banner

卡頓問題一(3個 UIImageView 思路)

Aiqiyi.gif

Youku.gif

通過卡頓頻率,我猜想這兩個項目的Banner思路應該一樣,用的三個 UIImageView 。

不知道動圖你是否看的卡頓的問題,如果你手機上恰好裝了這兩個App,可以自己試一下,很簡單,只要快速滑動就可以了。

但是這兩個的PageControl還是處理得很好的,能實時滾動到相應的位置。

卡頓問題二((N+2)個 UIImageView 思路)

Tianmao.gif

這個問題不好看出,因為他的卡頓頻率比較低,剛好是一組輪播視圖的周期。必須在第N+1張時才會復現。想看得清楚的小伙伴,如果自己項目Banner是這個思路可以測試一下自己項目的。

再看看這個PageControl的位置,在你快速滑動時,它是不動的,我猜想他控制PageControl的位置應該是在這個方法里做的

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { }

卡頓原因

就是這個兩個方法其中一個里計算cell位置的判斷條件不對

func scrollViewDidScroll(_ scrollView: UIScrollView) { }

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { }

Tab切換卡中間,不能復位

由于這個問題比較難復現,我就用自己的Demo測試的

UICollectionView實現,會自動修復

Test.gif

UIScrollView實現,需手動修復

HalfScreen.gif

動圖中應該可以清楚的看到滾動視圖滾動的坐標不對。

原因

這個具體原因我也不知道,這是所有輪播都會發生的問題,我猜想是跟內部的RunLoop應該有關。

還有的Banner是pageControl和cell聯動不及時,比如 咸魚

因為是在這里處理控制pageControl的位置的

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { }

簡書Banner的pageControl向左手動拖動時又太靈敏。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let page = scrollView.contentOffset.x / scrollView.frame.width
        if page <= 0.0 {
            // 向右拉
            collectionView?.scrollToItem(at: IndexPath(item: urlStrs.count - 2, section: 0), at: .centeredHorizontally, animated: false)
            pageControl?.currentPage = urlStrs.count - 3
        } else if page >= CGFloat(urlStrs.count - 1) {
            // 向左
            pageControl?.currentPage = 0
            collectionView?.scrollToItem(at: IndexPath(item: 1, section: 0), at: .centeredHorizontally, animated: false)
        } else {
            let value = page.truncatingRemainder(dividingBy: 1) < 0.5
            if value { // cell過半才改變pageControl(簡書的Banner應該沒有這個判斷)
                pageControl?.currentPage = Int(page) - 1
            }
        }
    }

 

 

來自:http://www.jianshu.com/p/97037c126d7c

 

 本文由用戶 KarSVO 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!