[toc]
故事背景
- 產(chǎn)品經(jīng)理:巴拉巴拉,巴拉巴拉香伴,巴拉巴拉祖驱。。瞒窒。捺僻。
- 我:你在講什么,我一句沒聽懂,能不能表達清楚一點
- 產(chǎn)品經(jīng)理:你手機有裝天貓嗎匕坯?
- 我:沒有束昵??葛峻?(我在想應該是從天貓哪里仿過來的)
- 產(chǎn)品經(jīng)理:我給你看一下吧锹雏,就是要做這種效果,能做嗎术奖?
- 我:能做(就是這么自信)礁遵,我先跟 Android 和 H5 開發(fā)溝通一下!2杉恰佣耐!
需求分析
- banner切換的時候,改變 banner 背景區(qū)域顏色顏色
- banner 按頁滾動
- 在沒有手勢的情況下唧龄,2 秒 banner 自動切換
- 支持手動滑動切換
- 手勢開始觸摸 banner兼砖,停止自動切換
- 手勢停止觸摸,開始自動切換
- 當前背景顏色 = 當前頁banner對應的背景顏色 + (下一頁banner 對應背景顏色 - 當前頁banner對應的背景顏色)* 下一頁banner相對于父視圖可見區(qū)域的比例
- banner 和 banner 的背景顏色都是運營配置并下發(fā)的客戶端的
實現(xiàn)思路
假設有 bannerList 和 bannerBackgroundColorList 兩個列表, bannerList 中裝的是 banner 數(shù)據(jù)既棺,bannerBackgroundColorList 中裝的是每一個 banner 對應的背景顏色數(shù)據(jù),每一個 banner 對應一個 color
NSArray *bannerList = @[banner1, banner2, banner3, banner4];
NSArray *bannerBackgroundColorList = @[color1, color2, color3, color4];
實現(xiàn)ScrollView 的代理讽挟,監(jiān)聽滑動過程,實現(xiàn)如下方法
- (void)scrollDidScroll:(UIScrollView *)scrollView {
//...
}
取得開始頁和結(jié)束頁背景顏色
取得當前頁
NSInteger startPage = scrollView.contentOffset.x / scrollView.width;
UIColor *startColor = bannerBackgroundColorList[startPage];
取得將要顯示的下一頁
NSInteger nextPage = startPage + 1;
if (nextPage >= bannerBackgroundColorList.count){
nextPage = 0;
}
UIColor *endColor = bannerBackgroundColorList[nextPage];
取得結(jié)束頁出現(xiàn)的比例丸冕,計算公式如下
p = (scrollView.offset.x%scrollView.width)/scrollView.width
scrollView.offset.x 為滾動視圖的 x 方向的偏移量耽梅,scrollView.width 為滾動視圖的寬度
將取得顏色轉(zhuǎn)換為RGBA色值
如果顏色本身是一個后端傳遞過來的 16 進制色值,則采用下面的方式
/** 提取十六進制字符串中的色值 */
BOOL YSYHexStrToRGBA(NSString *str,
NSInteger *r, NSInteger *g, NSInteger *b, NSInteger *a) {
str = [str uppercaseString];
if ([str hasPrefix:@"#"]) {
str = [str substringFromIndex:1];
} else if ([str hasPrefix:@"0X"]) {
str = [str substringFromIndex:2];
}
NSUInteger length = [str length];
// RGB RGBA RRGGBB RRGGBBAA
if (length != 3 && length != 4 && length != 6 && length != 8) {
return NO;
}
//RGB,RGBA,RRGGBB,RRGGBBAA
if (length < 5) {
*r = YSYHexStrToInt([str substringWithRange:NSMakeRange(0, 1)]);
*g = YSYHexStrToInt([str substringWithRange:NSMakeRange(1, 1)]);
*b = YSYHexStrToInt([str substringWithRange:NSMakeRange(2, 1)]);
if (length == 4){
*a = YSYHexStrToInt([str substringWithRange:NSMakeRange(3, 1)]);
} else {
*a = 255;
}
} else {
*r = YSYHexStrToInt([str substringWithRange:NSMakeRange(0, 2)]);
*g = YSYHexStrToInt([str substringWithRange:NSMakeRange(2, 2)]);
*b = YSYHexStrToInt([str substringWithRange:NSMakeRange(4, 2)]);
if (length == 8) {
*a = YSYHexStrToInt([str substringWithRange:NSMakeRange(6, 2)]);
} else {
*a = 255;
}
}
return YES;
}
如果顏色是一個 UIColor 類型的對象則采用 UIColor 類提供的方法
- (BOOL)getRed:(CGFloat *)R green: (CGFloat *)G blue:(CGFloat *)B alpha:(CGFloat *)A
這里假設bannerBackgroundColorList 里的元素 UIColor 類型的
CGFloat startR,startG,startB,startA,endR,endG,endB,endA;
[startColor getRed:&startR green:&startG blue:&startB alpha:&startA];
[endColor getRed:&endR green:&endG blue:&endB alpha:&endA];
計算最終色值
R = startR + (endR - starR) * p;
G = startG + (endG - starG) * p;
B = startB + (endB - starB) * p;
A = startA + (endA - starA) * p;
將計算出來的色值轉(zhuǎn)換為顏色胖烛,得到 banner 背景當前要顯示的顏色
UIColor *currentColor = [UIColor colorWithRed:R green:G blue:B alpha:A];
總結(jié)
- 為了方便 banner 切換我這里使用 GitHub 開源庫 SDCycleScrollView褐墅,挺好用的
- 技術(shù)要點就是取兩個顏色的中間顏色,顏色由R洪己、G妥凳、B、A構(gòu)成(準確一點來說是由 R答捕、G逝钥、B 三色值構(gòu)成),取中間顏色拱镐,也就是對開始顏色的RGBA值跟結(jié)束顏色的RGBA值進行運算得到最終的RGBA色值艘款,將色值再轉(zhuǎn)換為顏色