SwiftUI bir listeden satırları sil

Oct 24 2020

Resimden de görebileceğiniz gibi bir renk listem var, bir rengi de array.

Bir liste ekleyin ve sonra aramaya çalıştı onDeletearamayı ForEach, ama iyi çalışıyor bana sorunları veriyor değil.

Daha sonra buna ek olarak, listenin içerdiği elemanların boyutunda olmasını istiyorum.

Hata:

Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444

Birisi bana biraz tavsiye verebilir mi?

Kod:

import SwiftUI

struct ContentView: View {
    var cornerRadius: CGFloat = 16
    
    @State public var select = 2
    @State public var bgColors: [Color] =
        [
            Color(red: 21.0/255.0, green: 101.0/255.0, blue: 192.0/255.0),
            Color(red: 255.0/255.0, green: 193.0/255.0, blue: 7.0/255.0),
            Color(red: 76.0/255.0, green: 175.0/255.0, blue: 80.0/255.0)
        ]
    @Environment(\.colorScheme) var colorScheme
    
    @State var isShowPicker: Bool = false
    @State var image: Image? = Image("placeholder")
    
    @State private var url: String = "https://a.wattpad.com/useravatar/climaxmite.256.718018.jpg"
    
    init() {
        // Segmented control colors
        UISegmentedControl.appearance().backgroundColor = .systemGray6
        UISegmentedControl.appearance().selectedSegmentTintColor = UIColor(Color.blue)
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.systemBackground], for: .selected)
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.label], for: .normal)
    }
    
    var body: some View {
        VStack{
            
            ZStack {
                RoundedRectangle(cornerRadius: cornerRadius)
                    .frame(width: UIScreen.main.bounds.width-40, height: 100, alignment: .center)
                    .foregroundColor(colorScheme == .dark ? .black : .white)
                VStack(spacing: 12) {
                    ZStack {
                        Rectangle()
                            .frame(width: UIScreen.main.bounds.width-47, height: 35, alignment: .center)
                            .foregroundColor(Color(UIColor.systemGray6))
                            .cornerRadius(cornerRadius, corners: [.topLeft, .topRight])
                        Text("Select Background")
                            .foregroundColor(Color(UIColor.label))
                            .font(.subheadline)
                            .bold()
                    }
                    Picker(selection: $select, label: Text("Select Background")) { Text("Url").tag(0) Text("Select Image").tag(1) Text("Gradient").tag(2) }.pickerStyle(SegmentedPickerStyle()) .padding(EdgeInsets(top: 0, leading: 30, bottom: 0, trailing: 30)) Spacer() .frame(height: 3) } } if self.select == 0 { VStack{ ZStack { RoundedRectangle(cornerRadius: cornerRadius) .frame(width: UIScreen.main.bounds.width-40, height: 42, alignment: .center) .foregroundColor(Color(UIColor.systemBackground)) TextField("http://", text: $url)
                            .padding(10)
                            .frame(width: UIScreen.main.bounds.width-40)
                            .foregroundColor(Color(UIColor.label))
                            .cornerRadius(cornerRadius)
                            .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 10))
                    }
                    
                    Button(action: {
                        
                    }, label: {
                        Text("Submit")
                            .foregroundColor(Color(UIColor.systemBackground))
                            .bold()
                    })
                    .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20))
                    .foregroundColor(.white)
                    .font(.subheadline)
                    .background(Color.blue)
                    .cornerRadius(cornerRadius)
                }
            }
            
            if self.select == 1 {
                VStack {
                    Button(action: {
                        withAnimation {
                            self.isShowPicker.toggle()
                        }
                    }) {
                        Image(systemName: "photo")
                            .font(.headline)
                            .foregroundColor(colorScheme == .dark ? .white : .black)
                        Text("Import")
                            .font(.headline)
                            .foregroundColor(colorScheme == .dark ? .white : .black)
                        
                    }
                    .foregroundColor(.black)
                }
                .sheet(isPresented: $isShowPicker) { ImagePicker(image: self.$image)
                }
            }
            
            if self.select == 2 {
                VStack(alignment: .trailing){
                    Button(action: {
                        bgColors.append(Color.clear)
                    }) {
                        Image(systemName: "plus")
                            .font(.headline)
                            .foregroundColor(colorScheme == .dark ? .white : .black)
                            .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 15))
                    }
                    
                    List {
                        
                        ForEach(Array(bgColors.enumerated()), id: \.offset) { index, element in
                            ZStack {
                                ColorPicker("Set the background color", selection: $bgColors[index]) } .padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 10)) } .onDelete(perform: delete) }.background(Color.blue) } } Spacer() } .padding(.top, 25) .ignoresSafeArea(.keyboard) .background(Color(UIColor.systemGray6)) .edgesIgnoringSafeArea(.all) } func delete(at offsets: IndexSet) { bgColors.remove(atOffsets: offsets) } } struct RoundedCorner: Shape { var radius: CGFloat = .infinity var corners: UIRectCorner = .allCorners func path(in rect: CGRect) -> Path { let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) return Path(path.cgPath) } } extension View { func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View { clipShape( RoundedCorner(radius: radius, corners: corners) ) } } // extension for keyboard to dismiss extension UIApplication { func endEditing() { sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } } struct ImagePicker: UIViewControllerRepresentable { @Environment(\.presentationMode) var presentationMode @Binding var image: Image? class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @Binding var presentationMode: PresentationMode @Binding var image: Image? init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) { _presentationMode = presentationMode _image = image } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage image = Image(uiImage: uiImage) presentationMode.dismiss() } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { presentationMode.dismiss() } } func makeCoordinator() -> Coordinator { return Coordinator(presentationMode: presentationMode, image: $image)
    }
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController,
                                context: UIViewControllerRepresentableContext<ImagePicker>) {
        
    }
    
}

Yanıtlar

2 George_E Oct 24 2020 at 14:31

Sorun şu ki List, idsizde verirsiniz \.offset. Ancak, içindeki verileri kaldırdığınız bgColorsiçin bu veriler değişebilir. Bunun yerine, her renk için sabit olacağı için idolarak ayarlamalısınız \.element.

ColorListeden bir a çıkardığınızda çöken bu basitleştirilmiş örneği düşünün :

struct ContentView: View {
    
    @State private var arr: [Color] = [.red, .green, .blue]

    var body: some View {
        List {
            ForEach(Array(arr.enumerated()), id: \.offset) { (index, _) in
                ColorPicker("Color", selection: $arr[index])
            }
            .onDelete(perform: delete)
        }
    }
    
    private func delete(at offsets: IndexSet) {
        arr.remove(atOffsets: offsets)
    }
}

Ve değişikliklerin renge idverildiği Listve yeninin olduğu çalışma örneği Binding:

struct ContentView: View {

    @State private var arr: [Color] = [.red, .green, .blue]

    var body: some View {
        List {
            ForEach(Array(arr.enumerated()), id: \.element) { (index, _) in
                ColorPicker(
                    "Color",
                    selection: Binding<Color>(
                        get: { arr[index] },
                        set: { arr[index] = $0 }
                    )
                )
            }
            .onDelete(perform: delete)
        }
    }

    private func delete(at offsets: IndexSet) {
        arr.remove(atOffsets: offsets)
    }
}