国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

iOS 頁(yè)面滑動(dòng)與標(biāo)題切換顏色漸變的聯(lián)動(dòng)效果實(shí)例

2019-10-21 18:47:12
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

話不多說(shuō),直接上圖,要實(shí)現(xiàn)類似如下效果。

ios,導(dǎo)航欄滑動(dòng)漸變,標(biāo)題欄漸變

這個(gè)效果非常常見(jiàn),這里著重講講核心代碼

封裝頂部的PageTitleView

封裝構(gòu)造函數(shù)

封裝構(gòu)造函數(shù),讓別人在創(chuàng)建對(duì)象時(shí),就傳入其實(shí)需要顯示的內(nèi)容 frame:創(chuàng)建對(duì)象時(shí)確定了

  1. frame就可以直接設(shè)置子控件的位置和尺寸
  2. isScrollEnable:是否可以滾動(dòng)。某些地方該控件是可以滾動(dòng)的。
  3. titles:顯示的所有標(biāo)題
// MARK:- 構(gòu)造函數(shù)init(frame: CGRect, isScrollEnable : Bool, titles : [String]) {selfisScrollEnable = isScrollEnableselftitles = titlessuperinit(frame: frame)}

設(shè)置UI界面

設(shè)置UI界面

  1.  添加UIScrollView,如果標(biāo)題過(guò)多,則可以滾動(dòng)
  2. 初始化所有的Label,用于顯示標(biāo)題。并且給label添加監(jiān)聽(tīng)手勢(shì)
  3. 添加頂部線和滑塊的View

實(shí)現(xiàn)相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,這里代碼從略

封裝底部的PageCotentView

封裝構(gòu)造函數(shù)

封裝構(gòu)造函數(shù),讓別人在創(chuàng)建對(duì)象時(shí),就傳入其實(shí)需要顯示的內(nèi)容

  1. 所有用于顯示在UICollectionView的Cell的所有控制器
  2. 控制器的父控制器
// MARK:- 構(gòu)造函數(shù)init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController) {selfchildVcs = childVcsselfparentViewController = parentViewControllersuperinit(frame: frame)}

設(shè)置UI界面內(nèi)容

設(shè)置UI界面

  1. 將所有的子控制器添加到父控制器中
  2. 添加UICollectionView,用于展示內(nèi)容
// MARK:- 懶加載屬性private lazy var collectionView : UICollectionView = {// 1.創(chuàng)建布局let layout = UICollectionViewFlowLayout()layout.itemSize = self.bounds.sizelayout.minimumLineSpacing = 0layout.minimumInteritemSpacing = 0layout.scrollDirection = .Horizontal// 2.創(chuàng)建collectionViewlet collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)collectionView.showsHorizontalScrollIndicator = falsecollectionView.pagingEnabled = truecollectionView.bounces = falsecollectionView.scrollsToTop = falsecollectionView.dataSource = selfcollectionView.delegate = selfcollectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: kContentCellID)return collectionView}()private func setupUI() {// 1.添加所有的控制器for childVc in childVcs {parentViewController?.addChildViewController(childVc)}// 2.添加collectionViewaddSubview(collectionView)}

實(shí)現(xiàn)UICollectionView的數(shù)據(jù)源方法

  1. 在返回Cell的方法中,先將cell的contentView中的子控件都移除,防止循環(huán)引用
  2. 取出indexPath.item對(duì)應(yīng)的控制器,將控制器的View添加到Cell的contentView中
// MARK:- 遵守UICollectionView的數(shù)據(jù)源extension PageContentView : UICollectionViewDataSource {func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {return childVcs.count}func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kContentCellID, forIndexPath: indexPath)// 移除之前的for subview in cell.contentView.subviews {subview.removeFromSuperview()}// 取出控制器let childVc = childVcs[indexPath.item]childVc.view.frame = cell.contentView.boundscell.contentView.addSubview(childVc.view)return cell}}

PageTitleView點(diǎn)擊改變PageContentView

通過(guò)代理將PageTitleView的事件傳遞出去

/// 定義協(xié)議protocol PageTitleViewDelegate : class {func pageTitleView(pageTitleView : PageTitleView, didSelectedIndex index : Int)}@objc private func titleLabelClick(tapGes : UITapGestureRecognizer) {// 1.獲取點(diǎn)擊的下標(biāo)志guard let view = tapGes.view else { return }let index = view.tag// 2.滾到正確的位置scrollToIndex(index)// 3.通知代理delegate?.pageTitleView(self, didSelectedIndex: index)}

內(nèi)部調(diào)整

// 內(nèi)容滾動(dòng)private func scrollToIndex(index : Int) {// 1.獲取最新的label和之前的labellet newLabel = titleLabels[index]let oldLabel = titleLabels[currentIndex]// 2.設(shè)置label的顏色newLabel.textColor = kSelectTitleColoroldLabel.textColor = kNormalTitleColor// 3.scrollLine滾到正確的位置let scrollLineEndX = scrollLine.frame.width * CGFloat(index)UIView.animateWithDuration(0.15) {self.scrollLine.frame.origin.x = scrollLineEndX}// 4.記錄indexcurrentIndex = index}

在PageContentView中設(shè)置當(dāng)前應(yīng)該滾動(dòng)的位置

// MARK:- 對(duì)外暴露方法extension PageContentView { func scrollToIndex(index : Int) {let offset = CGPoint(x: CGFloat(index) * collectionViewboundswidth, y: 0) collectionViewsetContentOffset(offset, animated: false)}}

PageContentView滾動(dòng)調(diào)整PageTitleView

通過(guò)觀察,我們發(fā)現(xiàn):

                1> 原來(lái)位置的Title顏色會(huì)逐漸變暗

                2> 目標(biāo)位置的Title顏色會(huì)逐漸變亮

                3> 變化程度是和滾動(dòng)的多少相關(guān)

由此得出結(jié)論:

我們一共需要獲取三個(gè)值

1> 起始位置下標(biāo)值

2> 目標(biāo)位置下標(biāo)值

3> 當(dāng)前滾動(dòng)的進(jìn)度

其實(shí)前2點(diǎn)可以由第3點(diǎn)計(jì)算而來(lái),可以只需要將進(jìn)度傳遞出去。

根據(jù)進(jìn)度值處理標(biāo)題顏色漸變及滑塊邏輯

         。當(dāng)前進(jìn)度值唯一確定了標(biāo)題的狀態(tài),計(jì)算出需要發(fā)生顏色變化的兩相鄰標(biāo)題索引

         。注意:下標(biāo)值需要防止越界問(wèn)題,臨界點(diǎn)的處理

實(shí)現(xiàn)代碼

extension PageContentView : UICollectionViewDelegate {func scrollViewWillBeginDragging(scrollView: UIScrollView) {startOffsetX = scrollView.contentOffset.x}func scrollViewDidScroll(scrollView: UIScrollView) {// 0.判斷是否是點(diǎn)擊事件 if isForbidScrollDelegate { return }// 1.定義獲取需要的數(shù)據(jù) var progress : CGFloat = 0 let currentOffsetX = scrollView.contentOffset.x let scrollViewW = scrollView.bounds.width  // 1.計(jì)算progress  progress = currentOffsetX / scrollViewW  // 3.將progress傳遞給titleView delegate?.pageContentView(self, progress: progress) }}

根據(jù)滾動(dòng)傳入的值,調(diào)整PageTitleView

兩種顏色必須使用RGB值設(shè)置(方便通過(guò)RGB實(shí)現(xiàn)漸變效果)

private let kNormalRGB : (CGFloat, CGFloat, CGFloat) = (85, 85, 85)private let kSelectRGB : (CGFloat, CGFloat, CGFloat) = (255, 128, 0)private let kDeltaRGB = (kSelectRGB.0 - kNormalRGB.0, kSelectRGB.1 - kNormalRGB.1, kSelectRGB.2 - kNormalRGB.2)private let kNormalTitleColor = UIColor(red: 85/255.0, green: 85/255.0, blue: 85/255.0, alpha: 1.0)private let kSelectTitleColor = UIColor(red: 255.0/255.0, green: 128/255.0, blue: 0/255.0, alpha: 1.0)

調(diào)整scrollLine及兩個(gè)Label顏色漸變

// MARK:- 對(duì)外暴露方法extension PageTitleView func changeLabel(progress: CGFloat) {// 開(kāi)啟彈簧效果時(shí)的過(guò)濾處理 var progress = progress > 0 ? progress : 0  progress = progress <= CGFloat(titleLabels.count - 1) ? progress : CGFloat(titleLabels.count - 1) var leftLabelIndex = Int(floor(progress)) let ratio = progress - CGFloat(leftLabelIndex) //獲取leftLabel和rightLabel let leftLabel = titleLabels[leftLabelIndex] if leftLabelIndex >= 3{  leftLabelIndex = 3 } print("leftLabelIndex = /(leftLabelIndex)") var rightIndex = leftLabelIndex + 1 if rightIndex >= 3{  rightIndex = 3 } print("rightIndex = /(rightIndex)") let rightLabel = titleLabels[rightIndex] //滑塊的邏輯 let moveTotalX = leftLabel.frame.width let moveX = moveTotalX * ratio scrollLine.frame.origin.x = leftLabel.frame.origin.x + moveX //3.Label顏色的漸變 // 3.1.取出變化的范圍 let colorDelta = (kSelectedColor.0 - kNormalColor.0, kSelectedColor.1 - kNormalColor.1, kSelectedColor.2 - kNormalColor.2) if leftLabelIndex != rightIndex { // 3.2.變化leftLabel leftLabel.textColor = UIColor(r: kSelectedColor.0 - colorDelta.0 * ratio, g: kSelectedColor.1 - colorDelta.1 * ratio, b: kSelectedColor.2 - colorDelta.2 * ratio) // 3.2.變化rightLabel rightLabel.textColor = UIColor(r: kNormalColor.0 + colorDelta.0 * ratio, g: kNormalColor.1 + colorDelta.1 * ratio, b: kNormalColor.2 + colorDelta.2 * ratio) } // 4.記錄最新的index currentIndex = leftLabelIndex }}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到IOS開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 湟中县| 忻城县| 富裕县| 揭东县| 尼玛县| 乐业县| 三原县| 河北省| 桦川县| 宝丰县| 衡东县| 壤塘县| 曲阜市| 襄樊市| 星座| 平定县| 宕昌县| 永仁县| 禹州市| 修水县| 锡林浩特市| 阿拉善左旗| 融水| 连云港市| 定州市| 洛阳市| 江永县| 竹北市| 梅河口市| 天等县| 醴陵市| 博湖县| 武邑县| 西乌珠穆沁旗| 贡觉县| 南昌县| 湘西| 米易县| 太仆寺旗| 鄯善县| 平阴县|