SwiftUI 多圆形视图独立添加照片的实现逻辑修正
SwiftUI 多圆形独立选图功能实现修正
核心问题根源
- 原代码所有三个圆形视图共用同一个
@State private var image变量,该变量更新时所有绑定它的视图都会同步刷新,自然显示同一张图片 - 所有视图共用同一套选图相关的状态变量(
shouldPresentImagePicker、shouldPresentActionScheet等),没有区分当前触发选图的是哪一个圆形视图 - 重复编写三次完全相同的圆形选图逻辑,冗余度高,极易出现状态绑定错误
修正实现思路
- 把单个圆形选图逻辑抽成独立可复用组件,每个组件持有自己的图片状态和弹窗状态,完全独立互不干扰
- 父视图仅管理三个独立的组件实例,不需要关心内部选图逻辑
- 原有
SUImagePickerView功能逻辑无需修改,仅调整状态绑定的目标对象
完整代码实现
1. 独立圆形选图组件
struct CircleImagePicker: View { // 每个组件持有独立的图片状态,默认显示plus占位图 @State private var image: Image? = Image("plus") // 每个组件持有独立的弹窗状态,互不干扰 @State private var shouldPresentImagePicker = false @State private var shouldPresentActionSheet = false @State private var shouldPresentCamera = false // 外部传入尺寸参数,方便复用适配不同布局 let size: CGSize var body: some View { image! .resizable() .aspectRatio(contentMode: .fill) .frame(width: size.width, height: size.height) .clipShape(Circle()) .overlay(Circle().stroke(Color.yellow, lineWidth: 4)) .shadow(radius: 10) .onTapGesture { shouldPresentActionSheet = true } .sheet(isPresented: $shouldPresentImagePicker) { SUImagePickerView( sourceType: shouldPresentCamera ? .camera : .photoLibrary, image: $image, isPresented: $shouldPresentImagePicker ) } .actionSheet(isPresented: $shouldPresentActionSheet) { ActionSheet( title: Text("Choose mode"), message: Text("Please choose your preferred mode to set your profile image"), buttons: [ .default(Text("Camera"), action: { shouldPresentImagePicker = true shouldPresentCamera = true }), .default(Text("Photo Library"), action: { shouldPresentImagePicker = true shouldPresentCamera = false }), .cancel() ] ) } } }
2. 父视图SendPicture修正代码
struct SendPicture: View { var body: some View { GeometryReader{ geometry in VStack{ HStack{ Text("Picture") .font(.system(size: 60)) .frame(width: geometry.size.width, height: geometry.size.height / 10) .foregroundColor(.init(red: 45/255, green: 0/255, blue: 112/255)) Spacer().frame(height: geometry.size.height / 5) } VStack{ Text("Hi").frame(width: geometry.size.width, height: geometry.size.height / 10) } VStack{ Image("AstroGirl") .resizable() .aspectRatio(contentMode: .fit) .frame(width: geometry.size.width,height: geometry.size.height / 3) } // 替换原有的三个重复圆形为独立组件实例,增加间距优化布局 HStack(spacing: 20) { CircleImagePicker(size: CGSize(width: geometry.size.width / 5, height: geometry.size.height / 10)) CircleImagePicker(size: CGSize(width: geometry.size.width / 5, height: geometry.size.height / 10)) CircleImagePicker(size: CGSize(width: geometry.size.width / 5, height: geometry.size.height / 10)) } Spacer().frame(height: geometry.size.height / 10) VStack{ Button(action: { // 后续跳转逻辑 }, label: { Text("Giriş Yap") .frame(width: geometry.size.width / 3, height: 50) .padding(10) .font(Font.system(size: 30, weight: .medium, design: .serif)) .foregroundColor(.white) .background(RoundedRectangle(cornerRadius: 30)) .foregroundColor(.init(red: 45/255, green: 0/255, blue: 112/255)) }) } } } } }
3. 原有SUImagePickerView无需修改
你提供的SUImagePickerView实现逻辑正确,只要绑定到单个组件的独立image变量即可正常工作。
扩展说明
如果后续需要在父视图中获取三个圆形选中的图片,只需把CircleImagePicker内部的@State private var image改为@Binding var image: Image?,然后在父视图中定义三个独立的@State变量分别传入即可,无需改动其他逻辑。
内容的提问来源于stack exchange,提问作者GurkanEsen
相关产品推荐
相关产品推荐

