You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:45:05