SwiftUI中ForEach内带计算缩放值的Circle调用scaleEffect小于1不显示
问题原因
- 布局容器选择错误:你使用了
VStack作为容器,VStack会将子视图沿垂直方向依次排列,每个子视图默认占据独立的布局空间。你给ForEach设置的frame(width: maxSize, height: maxSize)会让每个Circle都占用100x100的布局位置,4个Circle总高度达到400,超出屏幕可视范围后就只能看到最底部的一个视图。另外scaleEffect仅做视觉缩放,不会修改视图的实际布局占位,即使缩小了视觉尺寸,视图还是会占满100x100的布局空间,不会自动重叠。 - 缩放计算逻辑错误:你的代码中
(current + 1) / count是整数运算,Swift中两个Int类型相除结果仍为Int,因此1/4、2/4、3/4的结果都是0,只有最后一个4/4结果为1,所以即使你能看到所有视图,前面三个也会因为缩放系数为0完全不可见。
解决方法
你需要使用ZStack作为容器,ZStack会将所有子视图堆叠在同一平面、默认居中对齐,刚好符合同心圆形的展示需求。同时修正缩放计算逻辑,先将数值转为CGFloat再做除法即可得到正确的缩放比例。
修改后的代码如下:
struct MultipleCirclesView: View { let maxSize: CGFloat = 100 let count: Int = 4 let color: Color = Color.red let borderLineWidth: CGFloat = 8 var body: some View { // 把VStack换成ZStack实现子视图堆叠 ZStack { ForEach(0..<count) { current in Circle() .strokeBorder(color, lineWidth: borderLineWidth) // 先转成CGFloat再做除法,避免整数运算错误 .scaleEffect(CGFloat(current + 1) / CGFloat(count)) } } // frame直接加在ZStack上,不需要写在ForEach内部 .frame(width: maxSize, height: maxSize) } }
该实现不需要单独编写4个Circle,仅通过ForEach循环生成,且frame没有写在ForEach内部,完全符合需求。运行后会生成4个同心红色圆环,最大的圆环占满100x100尺寸,最小的圆环尺寸为最大尺寸的25%。
内容的提问来源于stack exchange,提问作者Yrb
相关产品推荐
相关产品推荐

