40 mins

Yesterday, I complete a feature before I leave office, It costed me 40 mins. That’s a very common effect like this.
Fading
The message box is disappearing to the top end. To an experienced 2d game developer, it’s pretty clear what should you do to make it.

  1. Let’s say you have a layout like this.
    No Fading

  2. Draw a rect, and fill it with gradient colors (The filling with gradient colors feature is existing in any system if it provide coding abilities about graphic, be patient, find it), it can be any color, the key point is the alpha. Make sure the alpha value is 0 to the top , and the alpha goes to 1 to the bottom. Add it to the view. Now you have this.
    Gradient Box

  3. Be sure to adjust the position before you make it as a mask, then the magic happens.
    Fading

  4. One more step, if you scroll the tableview, you’ll find the gradient move away to with the contents. Because you never update the position of the gradient.
    Let make it work by acting the scroll event to modify the position.

    1
    2
    3
    4
    5
    6
    7
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.gradient.position = CGPointMake(0, scrollView.contentOffset.y + self.tableView.frame.origin.y);
    [CATransaction commit];
    }

Tips: Here is the simplest way to understand “mask” (I think).

What you see through the mask view before you perform it is what you can’t see when it becomes a mask.

Now it’s time to talk about where does this request come from.
A UI designer who is my pre-colleague and current good friend Viding. He’s working in a sub-company of Sina at BJ.
He complained about the iOS engineer in his team is a jerk, yesterday.
“He said it can’t be done!! He said it needs to do something transparent and that will cause some performance problems!”
Well, fuck that shit! I have only one question, if it can’t be done, why there are so many video live apps are using this as the default solution to the chat box?
Is there any divine making it?

What makes me be able to solve the problem in a couple of mins? I have so many key words to locate the answer.
“Objective-c UITableView Transparent to the edge.”
“Objective-c UITableView gradient fading out.”
OR
“How can I make UITableView disappearing gradiently to the top end?”
You’ll receive tons of answer from Stackoverflow, Reddit and Blogs.
One of them gives me the answer I need.
[https://www.cocoanetics.com/2011/08/adding-fading-gradients-to-uitableview/]

A lazybones programmer can be a disaster in a team, especially when a guy like this ask for help from me after 2 years since I leave BJ.

The full code in Objective-c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#import "MainViewController.h"

@interface MainViewController ()
@property(nonatomic) UITableView *tableView;
@property(nonatomic) NSMutableArray *data;
@property(nonatomic)CAGradientLayer *gradient;
@end

@implementation MainViewController

- (void)viewDidLoad {
[super viewDidLoad];


self.view.backgroundColor = [UIColor redColor];
UIImageView *bg = [[UIImageView alloc] initWithFrame:self.view.frame];
bg.image = [UIImage imageNamed:@"bg"];
[self.view addSubview:bg];


self.data = [NSMutableArray array];
for (NSInteger i = 0; i < 100; i++) {
[self.data addObject:@{@"text":@"hahahahhahaha"}];
}

self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height/2,
self.view.frame.size.width, self.view.frame.size.height/2) style:UITableViewStylePlain];
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.separatorColor = [UIColor clearColor];
[self.view addSubview:self.tableView];



self.gradient = [MainViewController tableViewGradientLayer];
self.gradient.frame = self.view.frame;
self.tableView.layer.mask = self.gradient;

}

+ (CAGradientLayer *)tableViewGradientLayer
{
UIColor *colorOne = [UIColor colorWithWhite:0.9 alpha:0];
UIColor *colorTwo = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.85 alpha:0.8];
UIColor *colorThree = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.7 alpha:1.0];

NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, colorThree.CGColor, nil];

NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:0.1];
NSNumber *stopThree = [NSNumber numberWithFloat:0.99];

NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, stopThree, nil];

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = colors;
gradientLayer.locations = locations;

return gradientLayer;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.gradient.position = CGPointMake(0, scrollView.contentOffset.y+self.tableView.frame.origin.y);
[CATransaction commit];
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.data.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [[UIView alloc] init];
cell.selectedBackgroundView = [[UIView alloc] init];
[cell setAccessoryType:UITableViewCellAccessoryNone];
NSDictionary *d = [self.data objectAtIndex:indexPath.row];
cell.textLabel.text = [d valueForKey:@"text"];
[cell.textLabel setTextColor:[UIColor whiteColor]];
return cell;
}


@end

If I like, I can make it in TypeScript, ActionScript, C#, or any platform that supports Game programming.
PS: That 40 mins includes I re-download the simulator for the Xcode.