卡牛-首頁自定義壁紙功能實現思路及部分代碼

分類:技術 時間:2016-10-24

卡牛信用卡管家項目簡介:6000萬卡族的共同選擇!信用卡人士必備的手機應用。業內唯一通過 CFCA 國家級金融機構安全認證的信用卡管理應用。

進隨手科技工作有一段日子了,卡牛 App 作為一個信用卡業界領跑的 App 居然沒有自定義壁紙的功能……(可能現在你看到的版本依然沒有這個功能,筆者在寫這篇文章的時候 feature 剛做好還沒有發版本)也是讓人有些摸不著頭腦。

后面了解到其實之前是有做這個功能的,后面因為不好看給去掉了(一會兒上圖告訴大家為啥不好看),如果做好看的話實現起來有幾個難點。

自定義壁紙難點

先 po 個圖出來看圖說話:

如圖是卡牛 App 的首頁,上面的天鵝是壁紙,壁紙下面是卡片信息,圖中紅色筆框出的區域是一些按鈕和推廣以及辦卡業務入口。上面說如果用戶自定義壁紙的話會很丑,比如把上面的天鵝壁紙換成一張色調不同的壁紙,下面的卡片區域背景色依然是這種暖色會非常突兀而且如果用戶自定義的壁紙顏色太淺會導致上面紅框圈住的部分得不到凸顯甚至看不到按鈕,所以當時就把這個功能下架了……

解決問題

當時的解決方案是預留了 6 張壁紙并且為壁紙做了卡片背景色和上面紅框圈住的主題色,切換壁紙的時候同時改變卡片背景色和相關入口的主題色。

不過這個解決方案放在現在的角度看自然是不過關的,一個有著一定用戶規模的業內領跑級 App 連個自定義壁紙功能都不放出來?說出來跟鬧著玩似得……于是我們要解決問題

解決問題思路

首先我們可以向之前的解決方案學習,用戶切換壁紙的時候上傳自己手機相冊的圖片或者隨手拍照一張,怎么能很好的修改卡片背景色和上面相關入口的顏色呢?

首先,要獲取用戶自定義壁紙的主色調。

獲取自定義壁紙主色

獲取主色調的代碼如下:

/**
* 根據圖片獲取圖片的主色調
*
* @param image 要獲取主色調的圖片
*
* @return 所提供圖片的主色
*/

(UIColor *)mostColor:(UIImage *)image {
#if __IPHONE_OS_VERSION_MAX_ALLOWED gt; __IPHONE_6_1
int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
#else
int bitmapInfo = kCGImageAlphaPremultipliedLast;
#endif

//第一步 先把圖片縮小 加快計算速度. 但越小結果誤差可能越大
CGSize thumbSize = CGSizeMake(20, 20);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
thumbSize.width,
thumbSize.height,
8,//bits per component
thumbSize.width*4,
colorSpace,
bitmapInfo);

CGRect drawRect = CGRectMake(0, 0, thumbSize.width, thumbSize.height);
CGContextDrawImage(context, drawRect, image.CGImage);
CGColorSpaceRelease(colorSpace);

//第二步 取每個點的像素值
unsigned char *data = http://www.tuicool.com/articles/CGBitmapContextGetData (context);

if (data =http://www.tuicool.com/articles/= NULL) return nil;

NSCountedSet *cls = [NSCountedSet setWithCapacity:thumbSize.width * thumbSize.height];

for (int x = 0; x lt; thumbSize.width; x) {
for (int y = 0; y lt; thumbSize.height; y) {
int offset = 4 * (x * y);

int red = data[offset];
int green = data[offset 1];
int blue = data[offset 2];
int alpha = data[offset 3];

NSArray *clr=@[@(red), @(green), @(blue), @(alpha)];
[cls addObject:clr];
}
}
CGContextRelease(context);

//第三步 找到出現次數最多的那個顏色
NSEnumerator *enumerator = [cls objectEnumerator];
NSArray *curColor = nil;

NSArray *MaxColor = nil;
NSUInteger MaxCount = 0;

while ((curColor = [enumerator nextObject]) != nil)
{
NSUInteger tmpCount = [cls countForObject:curColor];

if (tmpCount lt; MaxCount) continue;

MaxCount = tmpCount;
MaxColor = curColor;
}

return [UIColor colorWithRed:([MaxColor[0] intValue]/255.0f) green:([MaxColor[1] intValue]/255.0f) blue:([MaxColor[2] intValue]/255.0f) alpha:([MaxColor[3] intValue]/255.0f)];
}

Note:

這里面有一個坑:如果用戶選擇的圖片特別大,這個函數調用時長難以把控,而用戶需要立馬看到自定義壁紙設置上去的效果,這時候不可以用異步處理(用戶回到主頁面看不到自己剛才設置的壁紙)出個提示讓用戶苦等顯然是一個不成熟的解決思路,于是加入代碼:

//第一步 先把圖片縮小 加快計算速度. 但越小結果誤差可能越大
CGSize thumbSize = CGSizeMake(20, 20);

是不是看著不錯???

看著挺不錯的解決了問題,卻在解決之余挖出了第二個坑:壓縮圖片之后獲取主色速度很快,但是獲取主色可能與原始圖片的主色有偏差(壓縮程度越大偏差越大),我們是要把這個主色當做卡片背景色的如果偏差明顯一樣會使得壁紙與卡片銜接處突兀不自然。

所以我們要解決的第二個問題:自定義壁紙與卡片背景色的過渡

自定義壁紙與卡片背景色的過渡

這里用到了 CAGradientLayer ,代碼就不貼了,上網一查應該有相關介紹,是 iOS 開發中用于做顏色過渡的圖層。

Note:

這里 CAGradientLayer 用法有兩處坑:

  • 過渡時設置兩種顏色(在這兩種顏色之間過渡)如果一個設置為 [UIColor clearColor].CGColor 另一個是我們獲取到的主色,那么過渡效果會很不自然
  • 卡牛 App 首頁是可以下拉刷新的,由于 CALayer 不能設置約束,如果動態計算的話會卡頓

第一個問題,解決方法是設置兩個顏色均為我們獲取到的主色,靠近壁紙的一端設置透明度為 0 就好了……

第二個問題,解決方法是自定義一個 UIView 如下:

  (Class)layerClass {
return [CAGradientLayer class];
}

用這個 UIView 去替換之前的 CALayer 遮蓋在壁紙與卡片背景色銜接處。

修改其他入口按鈕顏色

最后一步就是處理之前圖片中紅框圈住的部分業務入口按鈕的顏色,代碼簡單貼一部分:

// 如果背景色色值和 gt; 600 則返回深色 反之 淺色
CGFloat red = 0;
CGFloat green = 0;
CGFloat blue = 0;
if ([[self customBackgroundColor] getRed:amp;red green:amp;green blue:amp;blue alpha:nil]) {
if ((red green blue) * 255 gt; 600) {
return [UIColor colorWithRed:0 green:0 blue:0 alpha:0.6];
}else {
return [UIColor colorWithRed:1 green:1 blue:1 alpha:0.7];
}
}else {
return [UIColor colorWithHex:0xaa8146];
}

我們這里的解決方式是獲取主色色值,計算色值和如果大于閾值(這里是600)則認為主色為淺色,返回一個透明的黑色。反之,主色為深色,則返回一個透明的白色,很簡單的處理方式。

筆者認為這里也可以用取反色等等方式來做,只要能使按鈕顏色與主色相差大,能夠凸顯出按鈕來就好。

解決成果

Note:

這里壁紙上面的入口并沒有按照上面說的那樣識別深淺色返回黑白透明色,而是默認白色(PM 的意思)


Tags: iOS開發

文章來源:http://blog-lision.com/2016/10/24/CardNiuCustomWal


ads
ads

相關文章
ads

相關文章

ad