2017-04-05 87 views
1

我試圖通過掩蓋UITableView的頂部來給出導航欄的錯覺。頂部應該有50%的不透明度,而其餘部分應該有100%的不透明度。具有多個alpha值的矩形CALayer蒙版

這是很容易做的一個CAGradientLayer,像這樣:

- (void)addTopOpacityMask 
{ 
    CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
    gradientLayer.frame = self.tableView.frame; 

    id transparent = (id)[UIColor clearColor].CGColor; 
    id opaque = (id)[UIColor blackColor].CGColor; 
    gradientLayer.colors = @[transparent, opaque, opaque]; 
    gradientLayer.locations = @[@0.1, @0.11, @1]; 
    self.tableView.superview.layer.mask = gradientLayer; 
} 

但是,從我所知道的,在locations屬性的每個值必須是唯一的,所以總是會有一個小的梯度(我不想要)。設置地點

@[@0.1, 0.10001, @1]; 

似乎是一個非常unsexy的解決方案,因爲你還需要的所述面罩進入位置翻譯的高度。

我想過使用CAShapeLayer並簡單地創建頂部作爲蒙版,請參閱下面的代碼,但是由於蒙版僅覆蓋頂部,因此顯然會切除表視圖的其餘部分。

- (void)addTopOpacityMask 
{ 
    CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.fillRule = kCAFillRuleEvenOdd; 
    shapeLayer.fillColor = [UIColor blackColor].CGColor; 
    shapeLayer.opacity = 0.5; 
    CGRect maskRect = CGRectMake(0, 0, CGRectGetWidth(self.tableView.frame), 76); 

    CGPathRef path = CGPathCreateWithRect(maskRect, NULL); 
    shapeLayer.path = path; 
    CGPathRelease(path); 

    self.tableView.superview.layer.mask = shapeLayer; 
} 

我錯過了什麼?

我想掩蓋它的原因,而不是在表視圖頂部添加50%透明視圖很簡單。表格視圖也具有透明背景,我只希望導航欄在用戶開始滾動時顯示出來(類似於雅虎天氣應用程序的工作/使用方式)。

編輯:

爲了澄清,這是它會是什麼樣子在默認情況下(注意,你不能看到導航欄):

enter image description here

,這是它會是什麼樣就像當你開始在表視圖向下滾動(表視圖的阿爾法被切斷,但我們不改變視圖的背景顏色,這是半透明):

enter image description here

回答

0

再次編輯:好的一次機會 - 這可能爲你工作。玩了一會兒......它似乎得到了你想要的效果,半透明的面具部分需要一個非常低的不透明度值。不管怎麼說,這個代碼:

- (void)addTopOpacityMask { 

    CGRect rect = _tableView.frame; 
    CGRect r = rect; 

    UIGraphicsBeginImageContext(rect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // fill a "top rect" with black at 5% opacity 
    r.size.height = 76; 

    CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.0 alpha:0.05].CGColor); 
    CGContextFillRect(context, r); 

    // fill the rest of the layer with black at 100% opacity 
    r.origin.y = 76; 
    r.size.height = rect.size.height; 

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor); 
    CGContextFillRect(context, r); 

    // grab a UIImage from the context 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    // create a Layer 
    CALayer *theLayer = [CALayer layer]; 

    // set the Layer content to the just-created image 
    theLayer.contents = (__bridge id _Nullable)(image.CGImage); 

    theLayer.frame = rect; 

    // mask the view holding the tableview 
    _tableView.superview.layer.mask = theLayer; 

} 

給了我這樣的結果:

enter image description here

enter image description here


編輯:不知道我看到什麼你看到......但是,你有沒有嘗試過 喜歡這個?

- (void)addTopOpacityMask 
{ 
    CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
    gradientLayer.frame = self.tableView.frame; 

    id transparent = (id)[UIColor clearColor].CGColor; 
    id opaque = (id)[UIColor blackColor].CGColor; 

    // use 4 color slots 
    gradientLayer.colors = @[transparent, transparent, opaque, opaque]; 

    // and 4 color locations (I don't get an error when using 2 of the same values) 
    gradientLayer.locations = @[@0.1, @0.11, @0.11, @1]; 

    self.tableView.superview.layer.mask = gradientLayer; 
} 

可以簡單地創建一個CALayer並給它一個半透明的背景顏色......事情是這樣的:

CALayer *theLayer = [CALayer alloc]; 
CGRect r = tableView.bounds; 
r.size.height = 76.0; 
theLayer.frame = r; 
theLayer.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5].CGColor; 
[tableView.superview.layer addSublayer:theLayer]; 

+0

這樣做會導致改變頂部的外觀。我基本上在桌面視圖上有一個76磅的頂部插入,並且在開始滾動之前,我希望僞造的導航欄不可見。只有當它下面有單元格時,纔會注意到桌面上有一些東西。就像這樣,但沒有漸變過渡和50%的不透明度,而不是0%:http://stackoverflow.com/questions/21559596/clear-color-background-nav-bar-but-still-float-above-all內容 –

+0

嗯....你最初說的「很容易做一個CAGradientLayer」,除非你仍然看到一個小的梯度外觀......你可以顯示代碼,讓你這麼遠? – DonMag

+0

我爲此添加了代碼。 –