SwiftUI 按钮作为 EditButton
SwiftUI Button as EditButton
如何使用像 EditButton
这样的按钮?
或者我如何使用按钮从列表中激活编辑模式?
或者我如何更改名称 EditButton
"edit" / "done"?
下面的实现将 EditButton
的功能替换为 Button
:
import SwiftUI
struct ContentView: View {
@State var isEditing = false
@State var selection = Set<String>()
var names = ["Karl", "Hans", "Faustao"]
var body: some View {
NavigationView {
VStack {
List(names, id: \.self, selection: $selection) { name in
Text(name)
}
.navigationBarTitle("Names")
.environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
Button(action: {
self.isEditing.toggle()
}) {
Text(isEditing ? "Done" : "Edit")
.frame(width: 80, height: 40)
}
.background(Color.yellow)
}
.padding(.bottom)
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
Result
但是,通过这样做,选择处理需要由我们自己实现(这可能是也可能不是问题)。
遗憾的是,目前没有太多相关文档:
https://developer.apple.com/documentation/swiftui/list/3367016-init
在 Beta 5 中有更好的方法,您可以直接获取 @Environment
绑定(最好将其设为导航栏项):
import SwiftUI
struct EditableListView: View {
@State var items: [String] = ["1", "2", "3"]
@State var selections: Set<String> = []
@Environment(\.editMode) private var editMode: Binding<EditMode>
var body: some View {
List(items, id: \.self, selection: $selections) { item in
Text(item)
}
.navigationBarItems(trailing:
Button(action: {
self.editMode?.value.toggle()
}) {
Text(self.editMode?.value == .active ? "Done" : "Edit")
}
)
.animation(.default)
}
}
extension EditMode {
mutating func toggle() {
self = self == .active ? .inactive : .active
}
}
这是一种在观察变化的同时保留 EditButton
功能的方法。
EditButton()
.simultaneousGesture(TapGesture().onEnded {
// Do your thing
})
这适用于您想要观察点击的每个视图。
您也可以使用如下所示的普通按钮:
.navigationBarItems(trailing: HStack{
Button(action: {
editMode?.wrappedValue.toggle()
}, label: {
Text(editButtinTxt)
})
})
和正文:
var editBtnTxt : String {
if let isEditing = editMode?.wrappedValue.isEditing {
return isEditing ? "Done" : "Edit"
}else {
return ""
}
}
别忘了
@Environment(\.editMode) var editMode
至于Xcode13,好像有更新。我测试以下代码是否有效。
@State var editMode: EditMode = .inactive
@State var isEditing = false
List {
.....
}.environment(\.editMode, $editMode)
Button(action: {
isEditing.toggle()
editMode = isEditing ? .active : .inactive
})
如何使用像 EditButton
这样的按钮?
或者我如何使用按钮从列表中激活编辑模式?
或者我如何更改名称 EditButton
"edit" / "done"?
下面的实现将 EditButton
的功能替换为 Button
:
import SwiftUI
struct ContentView: View {
@State var isEditing = false
@State var selection = Set<String>()
var names = ["Karl", "Hans", "Faustao"]
var body: some View {
NavigationView {
VStack {
List(names, id: \.self, selection: $selection) { name in
Text(name)
}
.navigationBarTitle("Names")
.environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
Button(action: {
self.isEditing.toggle()
}) {
Text(isEditing ? "Done" : "Edit")
.frame(width: 80, height: 40)
}
.background(Color.yellow)
}
.padding(.bottom)
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
Result
但是,通过这样做,选择处理需要由我们自己实现(这可能是也可能不是问题)。
遗憾的是,目前没有太多相关文档: https://developer.apple.com/documentation/swiftui/list/3367016-init
在 Beta 5 中有更好的方法,您可以直接获取 @Environment
绑定(最好将其设为导航栏项):
import SwiftUI
struct EditableListView: View {
@State var items: [String] = ["1", "2", "3"]
@State var selections: Set<String> = []
@Environment(\.editMode) private var editMode: Binding<EditMode>
var body: some View {
List(items, id: \.self, selection: $selections) { item in
Text(item)
}
.navigationBarItems(trailing:
Button(action: {
self.editMode?.value.toggle()
}) {
Text(self.editMode?.value == .active ? "Done" : "Edit")
}
)
.animation(.default)
}
}
extension EditMode {
mutating func toggle() {
self = self == .active ? .inactive : .active
}
}
这是一种在观察变化的同时保留 EditButton
功能的方法。
EditButton()
.simultaneousGesture(TapGesture().onEnded {
// Do your thing
})
这适用于您想要观察点击的每个视图。
您也可以使用如下所示的普通按钮:
.navigationBarItems(trailing: HStack{
Button(action: {
editMode?.wrappedValue.toggle()
}, label: {
Text(editButtinTxt)
})
})
和正文:
var editBtnTxt : String {
if let isEditing = editMode?.wrappedValue.isEditing {
return isEditing ? "Done" : "Edit"
}else {
return ""
}
}
别忘了
@Environment(\.editMode) var editMode
至于Xcode13,好像有更新。我测试以下代码是否有效。
@State var editMode: EditMode = .inactive
@State var isEditing = false
List {
.....
}.environment(\.editMode, $editMode)
Button(action: {
isEditing.toggle()
editMode = isEditing ? .active : .inactive
})