列表中的编辑模式
Posted
技术标签:
【中文标题】列表中的编辑模式【英文标题】:Edit mode in a List 【发布时间】:2019-09-23 14:41:38 【问题描述】:更新了工作代码。
我已经在我的应用程序中使用编辑模式实现了一个列表,因此我可以通过拖动行句柄来移动行。这很好用,但看起来不太好,因为移动图标位于行的内容下方(请参阅屏幕转储)。那是因为编辑模式为删除按钮腾出了空间。
在编辑模式下有没有办法隐藏行中的元素?
视图的代码是:
import SwiftUI
import Combine
import DateHelper
struct EggList: View
@EnvironmentObject var egg : Egg
@State private var eggs = Egg.all()
@State private var editMode: EditMode = .inactive
var body: some View
NavigationView
List
Image("Pantanal")
.resizable()
.frame(height: 250)
ForEach(eggs) eggItem in
NavigationLink(destination: EggDayList(eggItem: eggItem))
CellRow(eggItem: eggItem)
.environment(\.editMode, self.$editMode)
.onDelete(perform: delete)
.onMove(perform: move)
.navigationBarTitle(Text("Eggs"), displayMode: .inline)
.navigationBarItems(leading: EditButton(), trailing: NavigationLink(destination: Settings())
Text("Add Egg"))
.environment(\.editMode, self.$editMode)
func delete(at offsets: IndexSet)
eggs.remove(atOffsets: offsets)
func move(from source: IndexSet, to destination: Int)
eggs.move(fromOffsets: source, toOffset: destination)
struct CellRow: View
let eggItem: Egg
@Environment(\.editMode) private var editMode
var body: some View
HStack(spacing: 8)
Image(eggItem.species)
.resizable()
.frame(width: 48, height: 48)
.clipShape(Circle())
VStack(alignment: .leading, spacing: 0)
Text("\(eggItem.species)")
.font(.footnote)
.lineLimit(1)
.padding(.top, -4)
Text("id-"+String(eggItem.eggNumber))
.font(.footnote)
.lineLimit(1)
.padding(0)
Text("\(eggItem.layDate.string(with: "dd-MM-yy"))")
.font(.footnote)
.lineLimit(1)
.padding(.bottom, -7)
.frame(width: 90, alignment: .leading)
VStack(spacing: 2)
Text("days")
.font(.footnote)
.padding(.top, 12)
Image(systemName: "\(eggItem.diffToday)"+".circle")
.resizable()
.frame(width: 40, height: 30)
.padding(.bottom, 12)
.foregroundColor(.red)
.frame(width: 50, alignment: .leading)
VStack(spacing: 0)
Text("prediction")
.font(.footnote)
.padding(.top, 14)
Text(formatVar1(getal: eggItem.calcWeights[eggItem.daysToPip-1].prediction)+"%")
.font(.title)
.padding(.bottom, 12)
.frame(width: 80, alignment: .leading)
if !(self.editMode?.wrappedValue.isEditing ?? false)
VStack(alignment: .leading, spacing: 0)
Text("INC")
.font(.footnote)
.lineLimit(1)
.padding(.top, -4)
Text("37.3")
.font(.footnote)
.lineLimit(1)
.padding(0)
Text("30%")
.font(.footnote)
.lineLimit(1)
.padding(.bottom, -7)
.frame(width: 30, alignment: .leading)
Spacer()
VStack(alignment: .trailing, spacing: 0)
Image(systemName: "info.circle")
.resizable()
.frame(width: 22, height: 22)
.foregroundColor(.accentColor)
.onTapGesture(count: 1)
print("action")
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.frame(height: 46, alignment: .leading)
.padding(0)
【问题讨论】:
看起来您已经硬编码了元素的降级,因此单元格无法调整大小以进行编辑。您可以在编辑时隐藏元素。你能分享一些代码吗?解释如何实现它会容易得多。 按要求... 【参考方案1】:您的问题是,当您按下 EditButton 时,editMode
变量不会改变。无论处于何种状态,在您的 CellRow 中,editMode
变量始终返回 .inactive
。我不知道为什么,这可能是一个错误。
我遇到了同样的问题,但我在这里找到了这个问题:SwiftUI - How do I make edit rows in a list?,它通过将editMode
环境值传递给私有@State
变量来使用解决方法,这似乎很完美。
所以这是你需要做的:
将@State private var editMode: EditMode = .inactive
添加到您的 EggList 视图中。
在这会创建一个状态变量,从现在开始保持编辑模式。
.navigationBarItems(...)
之后的某处添加.environment(\.editMode, self.$editMode)
。
在这会将
EggList
中的环境变量editMode
设置为上述状态变量的绑定。
CellRow(...)
初始化器之后直接添加.environment(\.editMode, self.$editMode)
。
这会将状态变量
editMode
插入到CellRow
的环境中,可以通过@Environment(\.editMode)
访问它。
现在您可以将其中一个元素包装在 if 语句中,以便在处于编辑模式时将其隐藏:
if !self.editMode?.wrappedValue.isEditing ?? true
VStack(alignment: .leading, spacing: 0)
Text("INC")
.font(.footnote)
.lineLimit(1)
.padding(.top, -4)
Text("37.3")
.font(.footnote)
.lineLimit(1)
.padding(0)
Text("30%")
.font(.footnote)
.lineLimit(1)
.padding(.bottom, -7)
.frame(width: 30, alignment: .leading)
或者,如果您愿意,可以继续使用 LuLuGaGa 的 isHidden
扩展:
.isHidden(self.editMode?.wrappedValue.isEditing ?? false)
【讨论】:
猜你的意思是:@State private var isEditMode: EditMode = .inactive 感谢指正。但它仍然会抛出错误。 .environment(\.editMode, self.$editMode) 处出错。错误是“EggList”类型的值没有成员“$editMode”。 我明天可以自己测试一下,看看我是否也遇到了错误。 猜猜这是因为 editMode 私有 var 仅在 Cellrow 结构中已知。而不是在 EggList 结构中?【参考方案2】:为视图添加一个小扩展:
extension View
func isHidden(_ hidden: Bool) -> some View
if hidden
return AnyView(self.hidden())
else
return AnyView(self)
接下来将@Enviroment 添加到您的 CellRow:
@Environment(\.editMode) var editMode: Binding<EditMode>?
您将能够添加修饰符:
.isHidden(editMode?.wrappedValue.isEditing ?? false)
到您认为最不重要的堆栈之一。
【讨论】:
这听起来和我想要的完全一样……但是出了点问题。当我点击“编辑”按钮时,我看到一个“重建”并且“编辑”按钮文本变为“完成”。就是这样...我没有看到行前面的删除图标,也没有看到行句柄。带有 .ishidden 修饰符的堆栈仍然存在。 我需要查看声明列表能够提供帮助的视图的代码。以上是关于列表中的编辑模式的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 如何在编辑模式下避免列表中的行缩进,但不使用 onDelete? (附代码/视频)