SwiftUI-在编辑模式下而不使用onDelete时如何避免列表中的行缩进? (随附代码/视频)

时间:2020-04-18 05:42:59

标签: swiftui-list swiftui

在SwiftUI中,当我进入编辑模式而不使用onDelete时,如何避免行内容缩进列表中?这是当前发生这种情况时我的行内容缩进的方式,好像“删除”按钮将显示在左侧,但是我没有使用onDelete,所以那里没有按钮。

动画GIF

enter image description 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))
}

背景-实际上总是想一直处于编辑模式,即总是可以选择上下拖动行,但是永远不会使用Delete,因此希望查看onDelete的所有痕迹,在这种情况下是自动缩进..

更新:另一个示例(操场)如何发生不必要的缩进:

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)

enter image description here

3 个答案:

答案 0 :(得分:4)

也许值得向Apple提交请求,但这是默认行为。目前可以采用以下解决方法。在Xcode 11.4 / iOS 13.4上进行了测试。

demo

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)
    }
}

答案 1 :(得分:1)

也许不是很好的解决方法,但是您可以将列表扩展到左侧。

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

答案 2 :(得分:0)

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") )
        }
    }
}

}