You need to enable JavaScript to run this app. SwiftUI 多圆形视图独立添加照片的实现逻辑修正
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 13:06:04