objective c - How to fade between define colors with a dependent variable returning UIColor -
i want create function, in format shown in code below, fade between defined colors. purpose of function change color of table view cell depending on when data created; nsdate. function should consider time of day; 2015-07-07t12:00:00 have same color 2015-07-06t12:00:00.
@implementation nsdate (color_) - (uicolor *)daynightcolorbytimeofday { } @end the colors want "fade" between these:
- 12a #0525ff
- 6a #fff199
- 12p #ffd005
- 6p #059cff
- and 12a.
an example date passed function, datevalue = 3pm, return color between 2 colors, 12p , 6p. don't want animate.
each cell in table represents instance of array:
array { ... nsstring title, nsdate date ... }; the data in array.date set [nsdate date]. tell self, data type of nsdate, defendant variable.
the answer contains few ideas. first interpolation of colors. rgb representation can interpolated interpolating components, this:
// take 2 bounding colors , answer 1 pct distance between them - (uicolor *)colorbetween:(uicolor *)colora and:(uicolor *)colorb distance:(cgfloat)pct { cgfloat ar, ag, ab, aa; [colora getred:&ar green:&ag blue:&ab alpha:&aa]; cgfloat br, bg, bb, ba; [colorb getred:&br green:&bg blue:&bb alpha:&ba]; cgfloat rr = (1.0-pct)*ar + pct*br; cgfloat rg = (1.0-pct)*ag + pct*bg; cgfloat rb = (1.0-pct)*ab + pct*bb; cgfloat ra = (1.0-pct)*aa + pct*ba; return [uicolor colorwithred:rr green:rg blue:rb alpha:ra]; } we need interpolate times, can done approximately representing times minutes past midnight...
- (nsinteger)minutessincemidnightofdate:(nsdate *)date { nsdatecomponents *components = [[nscalendar currentcalendar] components:nsintegermax fromdate:date]; [components sethour:0]; [components setminute:0]; [components setsecond:0]; nsdate *midnight = [[nscalendar currentcalendar] datefromcomponents:components]; nsdatecomponents *diff = [[nscalendar currentcalendar] components:nscalendarunitminute fromdate:midnight todate:date options:0]; return [diff minute]; } we need represent parameters interpolation, done here directly possible given in question...
// macro convert hex value uicolor #define uicolorfromrgb(rgbvalue) \ [uicolor colorwithred:((float)((rgbvalue & 0xff0000) >> 16))/255.0 \ green:((float)((rgbvalue & 0x00ff00) >> 8))/255.0 \ blue:((float)((rgbvalue & 0x0000ff) >> 0))/255.0 \ alpha:1.0] now, work, find times (in minutes past midnight) before , after given time, colors corresponding times, interpolate colors proportion matching temporal distance between before , after times.
- (uicolor *)colorfordate:(nsdate *)date { // bounds of interpolation here nsarray *wheel = @[ @[ @0, uicolorfromrgb(0x0525ff) ], @[ @360, uicolorfromrgb(0xfff199) ], @[ @720, uicolorfromrgb(0xffd005) ], @[ @1080, uicolorfromrgb(0x059cff) ], @[ @1440, uicolorfromrgb(0x0525ff) ]]; nsinteger m = [self minutessincemidnightofdate:date]; // find index in wheel minute bound exceeds our date's minutes (m) nsinteger wheelindex = 0; (nsarray *pair in wheel) { nsinteger timeposition = [pair[0] intvalue]; if (m < timeposition) { break; } wheelindex++; } // wheelindex in 1..4, pair of bounds @ wheelindex // , preceding pair (-1). nsarray *priorpair = wheel[wheelindex-1]; nsarray *pair = wheel[wheelindex]; cgfloat priorminutes = [priorpair[0] intvalue]; cgfloat minutes = [pair[0] intvalue]; // how far between bounds pairs cgfloat minutespct = ((float)m - priorminutes) / (minutes - priorminutes); // , colors bounds pair uicolor *priorcolor = priorpair[1]; uicolor *color = pair[1]; // call color interpolation return [self colorbetween:priorcolor and:color distance:minutespct]; }
Comments
Post a Comment