SwiftUI menghapus baris dari daftar
Seperti yang Anda lihat dari gambar, saya memiliki daftar warna, saya juga ingin dapat memberikan kemungkinan untuk menghapus warna dari array.
Saya mencoba untuk menambahkan daftar dan kemudian memanggil onDeletepanggilan ForEach, tetapi tidak bekerja dengan baik itu memberi saya masalah.
Kemudian selain ini saya ingin daftar menjadi ukuran elemen yang terkandung.
Kesalahan:
Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444
Adakah yang bisa memberi saya nasihat?
Kode:
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>) {
}
}
Jawaban
Masalahnya adalah bahwa dalam diri Anda List, idAnda memberikannya \.offset. Namun, karena Anda menghapus data dari bgColors, maka data ini dapat berubah. Sebaliknya, Anda harus menetapkan idas \.elementkarena akan konstan untuk setiap warna.
Pertimbangkan contoh sederhana ini, yang lumpuh saat Anda menghapus Colordari daftar:
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)
}
}
Dan contoh kerja, di mana perubahan iddiberikan ke List, dan yang baru Bindingke warna:
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)
}
}