有幾種方法可以做到這一點。這裏有一種方法:
創建UIView
子命名GradientView
管理梯度層。這很有幫助,因爲這意味着您可以使用常規UIKit技術來管理漸變佈局(自動佈局約束,自動調整遮罩,UIKit動畫)。
對於應該參與共同梯度,添加一個GradientView
子視圖的每個視圖。同樣設置每個GradientView
的顏色,位置和起點和終點。
對於應該參與共同梯度,打開clipsToBounds
每個視圖。
使用自動佈局約束,以使每個GradientView
跨度所有參與superviews的。 (瞭解約束可以跨越超視圖/子視圖邊界很重要)。
通過這種方法,自動佈局需要使梯度覆蓋所有的意見,即使他們改變大小或走動的照顧。例如,當用戶旋轉設備時,您不必做任何特別的操作就可以使漸變效果更好。
因此,你的兩個視圖例如,我建議您設置視圖層次是這樣的:
在上面的觀點調試器的截圖,我禁用裁剪。您可以看到兩個漸變視圖具有相同的漸變並共享相同的屏幕空間。該topGradient
是topView
和bottomGradient
子視圖是bottomView
子視圖。
如果我們把剪裁上,你只會看到裏面topView
適合的topGradient
部分的界限,你只會看到裏面bottomView
適合的bottomGradient
部分的界限。下面是它看起來像剪貼啓用:
這是我的測試程序在模擬器的屏幕截圖:
這裏的源代碼GradientView
:
@interface GradientView: UIView
@property (nonatomic, strong, readonly) CAGradientLayer *gradientLayer;
@end
@implementation GradientView
+ (Class)layerClass { return CAGradientLayer.class; }
- (CAGradientLayer *)gradientLayer { return (CAGradientLayer *)self.layer; }
@end
下面是我用來創建所有視圖的代碼:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 50)];
topView.layer.cornerRadius = 10;
topView.clipsToBounds = YES;
UIView *topGradient = [self newGradientView];
[topView addSubview:topGradient];
[self.view addSubview:topView];
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(20, 90, 100, 50)];
bottomView.layer.cornerRadius = 10;
bottomView.clipsToBounds = YES;
UIView *bottomGradient = [self newGradientView];
[bottomView addSubview:bottomGradient];
[self.view addSubview:bottomView];
[self constrainView:topGradient toCoverViews:@[topView, bottomView]];
[self constrainView:bottomGradient toCoverViews:@[topView, bottomView]];
}
- (GradientView *)newGradientView {
GradientView *gv = [[GradientView alloc] initWithFrame:CGRectZero];
gv.translatesAutoresizingMaskIntoConstraints = NO;
gv.gradientLayer.colors = @[(__bridge id)UIColor.blueColor.CGColor, (__bridge id)UIColor.redColor.CGColor];
return gv;
}
這裏就是我如何創建,使一個GradientView
(或任何視圖)的約束涵蓋了一系列的觀點:
- (void)constrainView:(UIView *)coverer toCoverViews:(NSArray<UIView *> *)coverees {
for (UIView *coveree in coverees) {
NSArray<NSLayoutConstraint *> *cs;
cs = @[
[coverer.leftAnchor constraintLessThanOrEqualToAnchor:coveree.leftAnchor],
[coverer.rightAnchor constraintGreaterThanOrEqualToAnchor:coveree.rightAnchor],
[coverer.topAnchor constraintLessThanOrEqualToAnchor:coveree.topAnchor],
[coverer.bottomAnchor constraintGreaterThanOrEqualToAnchor:coveree.bottomAnchor]];
[NSLayoutConstraint activateConstraints:cs];
cs = @[
[coverer.leftAnchor constraintEqualToAnchor:coveree.leftAnchor],
[coverer.rightAnchor constraintEqualToAnchor:coveree.rightAnchor],
[coverer.topAnchor constraintEqualToAnchor:coveree.topAnchor],
[coverer.bottomAnchor constraintEqualToAnchor:coveree.bottomAnchor]];
for (NSLayoutConstraint *c in cs) { c.priority = UILayoutPriorityDefaultHigh; }
[NSLayoutConstraint activateConstraints:cs];
}
}
的greaterThanOrEqual
/lessThanOrEqual
的限制,這(默認)已要求優先,請確保coverer
覆蓋每個coveree
的整個幀。具有較低優先級的equal
約束條件確保coverer
佔用每個coveree
所需的最小空間。
一個「高」視圖與兩個圓角矩形「切口」通過圖層蒙版。 – DonMag