【问题标题】:.OnDelete not working with Realm data, How can I fix this?.OnDelete 不适用于 Realm 数据,我该如何解决?
【发布时间】:2021-05-12 05:25:27
【问题描述】:

当我运行我的应用程序并尝试滑动时,onDelete 没有出现并且不起作用。我没有机会真正测试它是否删除,因为当我滑动它时不允许我尝试删除它。我正在使用 RealmSwift 并发布了视图的代码以及我使用的 ViewModel。抱歉,如果这还不够代码,请告诉我,我会链接我的 GitHub 存储库,或分享更多代码。

import SwiftUI
import RealmSwift
import Combine

enum ActiveAlert{
    case error, noSauce
}

struct DoujinView: View {
    @ObservedObject var doujin: DoujinAPI
    //    @ObservedResults(DoujinInfo.self) var doujinshis
    @State private var detailViewShowing: Bool = false
    @State private var selectedDoujin: DoujinInfo?
    
    
    @StateObject var doujinModel = DoujinInfoViewModel()
    var body: some View {
        //Code if there are any Doujins
        ScrollView(.vertical) {
            LazyVStack(spacing: 0) {
                ForEach(doujinModel.doujins, id: \.UniqueID) { doujinshi in
                    Button(action: {
                        self.detailViewShowing = true
                        self.doujinModel.selectedDoujin = doujinshi
                        
                    }) {
                        DoujinCell(image: convertBase64ToImage(doujinshi.PictureString))
                    }
                }
                
                
                .onDelete(perform: { indexSet in
                                        self.doujinModel.easyDelete(at: indexSet)
                })
                
                
                //This will preseent the sheet that displays information for the doujin
                .sheet(isPresented: $detailViewShowing, onDismiss: {if doujinModel.deleting == true {doujinModel.deleteDoujin()}}, content: {
                    DoujinInformation(theAPI: doujin, doujinModel: doujinModel)
                })
                
                //                Loading circle
                if doujin.loadingCircle == true{
                    LoadingCircle(theApi: doujin)
                }
                
            }
            
        }
    }
}
enum colorSquare:Identifiable{
    var id: Int{
        hashValue
    }
    
    case green
    case yellow
    case red
}

class DoujinInfoViewModel: ObservableObject{
    var theDoujin:DoujinInfo? = nil
    var realm:Realm?
    var token: NotificationToken? = nil
    
    @ObservedResults(DoujinInfo.self) var doujins

    @Published var deleting:Bool = false
    @Published var selectedDoujin:DoujinInfo? = nil
    @Published var loading:Bool = false
        
    
    
    init(){
        let realm = try? Realm()
        self.realm = realm

        token = doujins.observe({ (changes) in
            switch changes{
            case .error(_):break
            case .initial(_): break
            case .update(_, deletions: _, insertions: _, modifications: _):
                self.objectWillChange.send()            }
        })
    }
    deinit {
        token?.invalidate()
    }
    
    var name: String{
        get{
            selectedDoujin!.Name
        }
    }

    var id: String {
        get {
            selectedDoujin!.Id
        }
    }
    var mediaID:String {
        get {
            selectedDoujin!.MediaID
        }
    }
    var numPages:Int{
        get {
            selectedDoujin!.NumPages
        }
    }
    var pictureString:String {
        get {
            selectedDoujin!.PictureString
        }
    }
    var uniqueId: String{
        get{
            selectedDoujin!.PictureString
        }
    }
    var similarity:Double{
        get {
            selectedDoujin!.similarity
        }
    }
    var color:colorSquare{
        get{
            switch selectedDoujin!.similarity{
            case 0...50:
                return .red
            case 50...75:
                return .yellow
            case 75...100:
                return .green
            default:
                return .green
            }
        }
    }
    
    var doujinTags: List<DoujinTags>{
        get {
            selectedDoujin!.Tags
        }
    }
    
    func deleteDoujin(){
            try? realm?.write{
                realm?.delete(selectedDoujin!)
            }
        deleting = false
    }
    
    func easyDelete(at indexSet: IndexSet){
        
        if let index = indexSet.first{
            let realm = doujins[indexSet.first!].realm
            try? realm?.write({
                realm?.delete(doujins[indexSet.first!])
            })
        }

    }
    
    func addDoujin(theDoujin: DoujinInfo){
        try? realm?.write({
            realm?.add(theDoujin)
        })
    }
    
}

【问题讨论】:

  • .onDelete 与 List no 一起为 LazyVStack 工作。
  • LazyVstack/VStack 有没有类似的东西

标签: swift swiftui realm


【解决方案1】:

.onDelete 仅适用于 List。对于LazyVStack,我们需要创建自己的滑动删除操作。

这是示例演示。您可以根据需要进行修改。

滑动删除行视图

struct SwipeDeleteRow<Content: View>: View {
    
    private let content: () -> Content
    private let deleteAction: () -> ()
    private var isSelected: Bool
    @Binding private var selectedIndex: Int
    private var index: Int
    
    init(isSelected: Bool, selectedIndex: Binding<Int>, index: Int, @ViewBuilder content: @escaping () -> Content, onDelete: @escaping () -> Void) {
        self.isSelected = isSelected
        self._selectedIndex = selectedIndex
        self.content = content
        self.deleteAction = onDelete
        self.index = index
    }
    
    @State private var offset = CGSize.zero
    @State private var offsetY : CGFloat = 0
    @State private var scale : CGFloat = 0.5
    
    var body : some View {
        HStack(spacing: 0){
            content()
                .frame(width : UIScreen.main.bounds.width, alignment: .leading)
            
            Button(action: deleteAction) {
                Image("delete")
                    .renderingMode(.original)
                    .scaleEffect(scale)
            }
        }
        .background(Color.white)
        .offset(x: 20, y: 0)
        .offset(isSelected ? self.offset : .zero)
        .animation(.spring())
        .gesture(DragGesture(minimumDistance: 30, coordinateSpace: .local)
                    .onChanged { gestrue in
                        self.offset.width = gestrue.translation.width
                        print(offset)
                    }
                    .onEnded { _ in
                        self.selectedIndex = index
                        if self.offset.width < -50 {
                            self.scale = 1
                            self.offset.width = -60
                            self.offsetY = -20
                        } else {
                            self.scale = 0.5
                            self.offset = .zero
                            self.offsetY = 0
                            
                        }
                    }
        )
    }
}

演示视图

struct Model: Identifiable {
    var id = UUID()
}

struct CustomSwipeDemo: View {
    
    @State var arr: [Model] = [.init(), .init(), .init(), .init(), .init(), .init(), .init(), .init()]
    
    @State private var listCellIndex: Int = 0
    
    var body: some View {
        ScrollView(.vertical) {
            LazyVStack(spacing: 0) {
                ForEach(arr.indices, id: \.self) { index in
                    SwipeDeleteRow(isSelected: index == listCellIndex, selectedIndex: $listCellIndex, index: index) {
                        if let item = self.arr[safe: index] {
                            Text(item.id.description)
                        }
                    } onDelete: {
                        arr.remove(at: index)
                        self.listCellIndex = -1
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                }
            }
        }
    }
}

辅助函数

//Help to preventing delete row from index out of bounds.
extension Collection where Indices.Iterator.Element == Index {
    subscript (safe index: Index) -> Iterator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

【讨论】:

  • 它可以工作,但是我收到此错误pastebin.com/yPW2sEnr。我正在尝试允许用户随意添加单元格
  • 只要在这一行评论 ``` DoujinCell(image: convertBase64ToImage(item.PictureString))``` 并添加普通文本并检查
  • 同人是数组吗?
  • 同人是,不断更新变化
  • 我没有经验。使用领域,但如果这是数组,那么您可以使用我的代码进行管理。
猜你喜欢
  • 2020-09-11
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多