• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 如何添加跨越两个 View 的渐变?

[复制链接]
菜鸟教程小白 发表于 2022-12-12 13:39:18 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我知道怎么做 (1),但我该怎么做 (2)?

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
CAGradientLayer *gradient = [CAGradientLayer layer];

gradient.frame = view.bounds;
gradient.colors = @[(id)[UIColor blueColor].CGColor, (id)[UIColor redColor].CGColor];

[view.layer insertSublayer:gradient atIndex:0];

enter image description here



Best Answer-推荐答案


有几种方法可以做到这一点。这是一种方法:

  1. 创建一个名为GradientViewUIView 子类来管理渐变层。这很有帮助,因为这意味着您可以使用普通的 UIKit 技术来管理渐变布局(自动布局约束、自动调整蒙版、UIKit 动画)。

  2. 对于每个应该参与公共(public)渐变的 View ,添加一个 GradientView subview 。将每个 GradientView 的颜色、位置以及起点和终点设置相同。

  3. 对于应该参与公共(public)渐变的每个 View ,打开 clipsToBounds

  4. 使用自动布局约束使每个 GradientView 跨越所有参与的 super View 。 (理解约束可以跨越父 View / subview 边界很重要)。

使用这种方法,自动布局会负责使渐变覆盖所有 View ,即使它们改变大小或四处移动。例如,当用户旋转设备时,您无需执行任何特殊操作即可使渐变效果很好。

因此,对于您的双 View 示例,我建议您设置这样的 View 层次结构:

unclipped

在上面的 View 调试器屏幕截图中,我禁用了剪辑。您可以看到两个渐变 View 具有相同的渐变并共享相同的屏幕空间。 topGradienttopView 的 subview ,bottomGradientbottomView 的 subview 。

如果我们打开剪裁,你将只能看到 topGradient 中适合 topView 边界的部分,而你只会看到 topGradient 的部分适合 bottomView 范围内的 code>bottomGradient。这是启用剪辑后的样子:

clipped

这是我在模拟器中的测试程序的屏幕截图:

screen shot

这是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

这是我用来创建所有 View 的代码:

- (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(或任何 View )覆盖一组 View 的约束:

- (void)constrainViewUIView *)coverer toCoverViewsNSArray<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 覆盖每个 的整个帧>被覆盖者equal 约束具有较低的优先级,然后确保 coverer 占用覆盖每个 coveree 所需的最小空间。

关于ios - 如何添加跨越两个 View 的渐变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45987883/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap