如何为LazyHGrid中选中的SF图标添加阴影效果
解决方案
核心思路是为每个图标按钮添加条件性的阴影修饰符,通过判断当前图标的id是否与选中的selectedIcon一致,来决定是否显示阴影。
修改后的完整代码如下:
struct ImageStore: Identifiable, Hashable { var iconName: String var id: Int } struct ContentView: View { let rows = [GridItem(.flexible())] let colors: [Color] = [.green, .red, .yellow, .blue] let imageName = [ ImageStore(iconName: "a.square.fill", id: 0), ImageStore(iconName: "b.square.fill", id: 1), ImageStore(iconName: "c.square.fill", id: 2), ImageStore(iconName: "d.square.fill", id: 3), ImageStore(iconName: "e.square.fill", id: 4), ImageStore(iconName: "f.square.fill", id: 5), ImageStore(iconName: "g.square.fill", id: 6), ] @State private var selectedIcon: Int = 0 var body: some View { VStack { ScrollView(.horizontal) { LazyHGrid(rows: rows, spacing: 20) { ForEach(imageName, id: \.self) { image in Button(action: { selectedIcon = image.id print("image name = \(image.iconName)") print("id = \(image.id)") print("selectedIcon = \(selectedIcon)") }) { Image(systemName: image.iconName) .font(.largeTitle) .foregroundColor(.white) .padding() .background(colors[image.id % colors.count]) // 关键:根据选中状态动态添加阴影 .shadow(color: .black, radius: selectedIcon == image.id ? 10 : 0) } } } } } } }
关键修改说明
- 在按钮的标签视图末尾添加了
.shadow修饰符,通过三元运算符判断:- 当
selectedIcon == image.id时,显示半径为10的黑色阴影(可根据需求调整阴影的颜色、半径、偏移量) - 未选中时,阴影半径设为0,相当于移除阴影
- 当
- 这种方式只会给当前选中的图标单独添加阴影,不会影响其他元素
为什么之前的方法失败
- 在按钮动作中放置图像:按钮的
action闭包是处理点击事件的逻辑区域,不能用来构建视图,所以会出现初始化器未使用的警告,属于概念混淆导致的错误。 - 给整个LazyHGrid加阴影:阴影修饰符作用在容器上时,会被容器内所有子元素继承,自然会导致所有图标都带上阴影,不符合需求。
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

