SwiftUI:如何在List的editMode中使Spacer不可选择?

huangapple go评论70阅读模式
英文:

SwiftUI: How can I make a Spacer in a List unselectable in editMode?

问题

I have a List view in my SwiftUI app(ios15.0 and above), and I need to add a Spacer at the end of the list to implement scrolling to the end, even if the last text has multiple lines.

然而,当列表进入编辑模式时,Spacer 也会获得一个复选标记,并且可以与最后一项一起选择。如何使 Spacer 不可选择?

I've tried adding the .disabled(true) modifier to the Spacer, but it doesn't seem to have any effect. Is there a way to make the Spacer unselectable without affecting the rest of the list?

我尝试将 .disabled(true) 修饰符添加到 Spacer,但似乎没有任何效果。有没有办法使 Spacer 无法选择,而不影响列表的其余部分?

Any help would be appreciated. Thank you!

任何帮助将不胜感激。谢谢!

英文:

I have a List view in my SwiftUI app(ios15.0 and above), and I need to add a Spacer at the end of the list to implement scrolling to the end, even if the last text has multiple lines.

However, when the list enters edit mode, the Spacer also gets a checkmark and can be selected with the last item. How can I make the Spacer unselectable?

I've tried adding the .disabled(true) modifier to the Spacer, but it doesn't seem to have any effect. Is there a way to make the Spacer unselectable without affecting the rest of the list?

Any help would be appreciated. Thank you!

enter edit mode:
SwiftUI:如何在List的editMode中使Spacer不可选择?

select last item or spacer:
SwiftUI:如何在List的editMode中使Spacer不可选择?

code for minimum implement:

struct TestScrollView: View {
    @State private var multiSelection = Set<String>()
    @State private var editMode = EditMode.inactive
    @State var messages: [String] = ["Item 1", "Item 2", "Item 3"]
    var body: some View {
        ScrollViewReader { scrollView in
            Button {
                editMode = EditMode.active
            } label: {
                Text("edit")
            }

            List(messages, id: \.self, selection: $multiSelection) { message in
                Text(message)
                .listRowSeparator(.hidden)
                
                if(message == messages.last) {
                    Spacer()
                        .id("end_text")
                        .disabled(true)
                }
            }.onAppear() {
                scrollView.scrollTo("end_text", anchor: .bottom)
            }.environment(\.editMode, $editMode)
        }
    }
}

答案1

得分: 1

The List初始化程序您正在使用会计算每次闭包调用的一行,每个消息都作为参数。它不会因为您将两个视图放入视图生成器闭包中而创建两行。它只能创建确切数量的 message.count 行。

因此,列表的最后一行包括 Text Spacer,这就是为什么您可以通过点击 TextSpacer 中的任何一个来选择它们。

Spacer 应该是它自己的行。使用一个允许您指定列表中所有行的初始化程序。

List(selection: $multiSelection) {
    ForEach(messages, id: \.self) { message in
        Text(message)
            .listRowSeparator(.hidden)
            .id(message)
    }
    Spacer().id("end_text")
}
.environment(\.editMode, $editMode)
.onAppear {
    scrollView.scrollTo("end_text", anchor: .bottom)
}
英文:

The List initialiser that you are using computes one row from each invocation of the closure, with each message as the parameter. It does not create two rows just because you put two views in the view builder closure. It can only create exactly message.count rows.

So the last row of the list consists of the Text and the Spacer, which is why you will select both by tapping on either the Text or the Spacer.

The Spacer should be its own row. Use an initialiser that allows you to specify all the rows of the list.

List(selection: $multiSelection) {
    ForEach(messages, id: \.self) { message in
        Text(message)
            .listRowSeparator(.hidden)
            .id(message)
    }
    Spacer().id("end_text")
}
.environment(\.editMode, $editMode)
.onAppear {
    scrollView.scrollTo("end_text", anchor: .bottom)
}

huangapple
  • 本文由 发表于 2023年5月14日 11:37:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76245709.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定