SwiftUI简明概念(4):如何对shape同时进行fill和stroke

1、iOS17方案

iOS17上可以同时对shape调用fill和stroke:

Circle()
    .stroke(.red, lineWidth: 20)
    .fill(.orange)
    .frame(width: 150, height: 150)

效果也如我们所预料的:

而且stroke可以调用任意次:

Circle()
    .stroke(.blue, lineWidth: 45)
    .stroke(.green, lineWidth: 35)
    .stroke(.yellow, lineWidth: 25)
    .stroke(.orange, lineWidth: 15)
    .stroke(.red, lineWidth: 5)
    .frame(width: 150, height: 150)

最终的效果是在Circle外边加了好几圈border。

2、iOS16方案

iOS16及之前虽然也有stroke、fill方法,但是将它们像iOS17那样写在一起是无效的。一个替代方案是使用strokeBorder或stroke给shape增加一个border来实现stroke的效果,然后用shape的fill版本来作为background,将它们叠在一起就能实现我们需要的效果:

Circle()
                .strokeBorder(.red, lineWidth: 20)
                .background(Circle().fill(.orange))
                .frame(width: 150, height: 150)
                .border(.green)

值得注意的一点是strokeBorder的调用对象是InsettableShapes,从视觉上看,border是加在shape的frame内的,而shape本身就好像被加了insets,变得越来越小了。而stroke版本,border中心恰好在frame边界上:

Circle()
                .stroke(.red, lineWidth: 20)
                .background(Circle().fill(.orange))
                .frame(width: 150, height: 150)
                .border(.green)

 

基于上面的方案,我们也很容易想到使用Zstack或者overlay来叠出相同的视觉效果:

ZStack {
    Circle()
        .fill(.orange)

    Circle()
        .strokeBorder(.red, lineWidth: 20)
}
.frame(width: 150, height: 150)

3、参考资料

How to fill and stroke shapes at the same time

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值