SwiftUI - how to avoid row indenting in List when in Edit Mode, but not using onDelete? (code/video attached)

自古美人都是妖i 提交于 2021-02-08 15:15:39

问题


In SwiftUI how can I avoid having row content being indenting in my List when I move into Edit Mode, but not using onDelete? That is currently my row content is indented as this happens, as if the "delete" button will be shown on the left, however I'm not using onDelete so there is no button there.

Animated GIF

Code extract here:

var body: some View {
    VStack{
        List() {
            ForEach(gcTasks) { gcTask in
                HStack {
                    GCTaskRow(withGcTask: gcTask, haha: "")
                }
            }
            // .onDelete(perform: self.deleteTask)   // NOTE: HAVE REMOVED
            .onMove(perform: self.move)
        }
    }
    .environment(\.editMode, listInEditMode ? .constant(.active) : .constant(.inactive))
}

Background - Actually want to move to being in EDIT mode always, i.e. so always have the option of dragging row up/down, however will never use Delete hence want to review all traces of onDelete, in this case being the automatic indentation..

UPDATE: Another example (playgrounds) of how the unwanted indenting is occuring:

import SwiftUI
import PlaygroundSupport

let modelData: [String] = ["Eggs", "Milk", "Bread"]

struct ListTestNoDelete: View {
    private func move(from uiStartIndexSet: IndexSet, to uiDestIndex: Int) {
        print("On Move")
    }
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(modelData, id: \.self) { str in
                        Text(str)
                    }
                    .onMove(perform: self.move)
                }
                .environment(\.editMode, .constant(.active))
                .navigationBarTitle( Text("Test") )
            }
        }
    }
}


let listTest = ListTestNoDelete()
PlaygroundPage.current.liveView = UIHostingController(rootView: listTest)


回答1:


Maybe not a very elegant fix but you could extend the List to the left.

List {
    // ...
}
// .padding(.leading, self.isEditing == .inactive ? 0 : -39)
.padding(.leading, self.isEditing ? -45 : 0)



回答2:


Maybe worth submitting request to Apple, but it is default behaviour. The following workaround is possible for now. Tested with Xcode 11.4 / iOS 13.4.

struct DemoListEditMode: View {

    @State var items = ["a","b","c","d","e"]

    var body: some View {
        List {
            ForEach(items, id: \.self) { z in
                HStack {
                    Image(systemName: "checkmark.square") // just for demo
                    Text("\(z)")
                }
            }.onMove(perform: self.move)
            .listRowInsets(EdgeInsets(top: 0, leading: -24, // workaround !!
                bottom: 0, trailing: 0))                    
        }
        .environment(\.editMode, .constant(.active)) // persistent edit mode
    }

    func move(source: IndexSet, destination: Int) {
        self.items.move(fromOffsets: source, toOffset: destination)
    }
}



回答3:


import SwiftUI 
let listEditModeOffsetX = -UIScreen.main.bounds.width*0.10647343
[enter image description here][1]//<<-- this is the padding that the list adds in left for delete button when in the edit mode. I calculated the constant and works fine on iPhone11 but you will need to check for each device separately for accurate offset for every device . 
let modelData: [String] = ["Eggs", "Milk", "Bread","Cake"]   
struct ContentView : View  {

@State var editingList = false
private func move(from source: IndexSet, to destination: Int) {
    modelData.move(fromOffsets: source, toOffset: destination)
    editingList = false
    print("On Move")
}
var body: some View {
    NavigationView {
        VStack {
            List {
                ForEach(modelData, id: \.self) { str in
                    Text(str)
                        .offset(x: self.editingList ? listEditModeOffsetX : 0)
                } .onMove(perform: self.move)
                .onLongPressGesture{
                    self.editingList = true
                }
               
            }
            .environment(\.editMode, editingList ? .constant(.active):.constant(.inactive))
            .navigationBarTitle( Text("Test") )
        }
    }
}

}



来源:https://stackoverflow.com/questions/61284711/swiftui-how-to-avoid-row-indenting-in-list-when-in-edit-mode-but-not-using-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!