Hi, I am building a view containing a list of struct objects. I have implemented the onMove to allow the list rows to be moved together with the toolbar EditButton. This works but I have a problem as per title, even when the EditButton is not clicked, i.e., not in editing mode, I still can move the list rows by long pressing the rows. I have searched high and low for a solution but couldn't find one that works perfectly.
Below is the code snippet.
I am a new iOS dev and really appreciate if someone could help me.
Many thanks!
@AppStorage("fruits") private var fruits = Fruits.fruits
var body: some View {
NavigationStack {
VStack {
List {
ForEach(fruits) { fruit in
NavigationLink(destination: FruitsView(title: fruit.title)) {
fruit.icon
Text(fruit.title)
}
}
.onMove { fruits.move(fromOffsets: $0, toOffset: $1) }
}
.environment(\.defaultMinListRowHeight, UIElementConstants.listCellHeight)
}
.toolbar { EditButton() }
.navigationTitle("Fruits")
}
}
struct Fruits: Identifiable, Codable {
var id: UUID
var title: String
var iconName: String
var icon: Image {
Image(systemName: self.iconName)
}
init(id: UUID = UUID(), title: String, iconName: String) {
self.id = id
self.title = title
self.iconName = iconName
}
}
extension Fruits {
static let fruits: [Fruits] = [
Fruits(
title: "Apple",
iconName: "basket.fill"),
Fruits(
title: "Banana",
iconName: "basket.fill"),
Fruits(
title: "Pineapple",
iconName: "basket.fill")
]
}
Post
Replies
Boosts
Views
Activity
Dear community,
I am a new developer and I am building a view (called Root) that has a list of rows where clicking each row navigates to a completely different view.
I have a CaseIteratable enum and I list each enum type using ForEach and each enum case navigates to a different view using NavigationLink and NavigationDestination. But the problem is that clicking any of the rows for the first time navigates correctly to the corresponding view. But when I go back to the root view and chose another row, it navigates me to a blank view for less than a sec and automatically navigates back to the root view.
Below is the code for reference.
I would really appreciate some help and advice here. Thank you very much!
struct RootViewNavigationStack: View {
@AppStorage("items") private var items = Item.allCases
@State private var enableMove = false
@State private var rootStackPath: NavigationPath = .init()
var body: some View {
NavigationStack(path: $rootStackPath) {
VStack {
List {
ForEach(items) { item in
HStack {
NavigationLink(value: item) {
ListCell(
icon: item.icon,
title: item.title)
}
.disabled(enableMove)
if enableMove {
withAnimation {
Image(systemName: "line.3.horizontal")
.foregroundStyle(.secondary)
}
}
}
}
.onMove(perform: enableMove == true ? moveItems : nil)
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
enableMove.toggle()
} label: {
if enableMove {
Text("Done")
.bold()
} else {
Text("Edit")
}
}
}
}
.navigationDestination(for: Item.self) { item in
item.destinationView
}
.navigationTitle("Root")
}
}
}
and this is the Item enum for more info
Just kindly ignore the var iconName since it doesnt represent any actual SF Symbol name
enum Item: Identifiable, Codable, Hashable, CaseIterable {
case view1
case view2
case view3
case view4
case view5
var id: Item { self }
}
extension Item {
var title: String {
switch self {
case .view1:
"View1"
case .view2:
"View2"
case .view3:
"View3"
case .view4:
"View4"
case .view5:
"View5"
}
}
var iconName: String {
switch self {
case .view1:
"View1"
case .view2:
"View2"
case .view3:
"View3"
case .view4:
"View4"
case .view5:
"View5"
}
}
var icon: Image {
Image(systemName: self.iconName)
}
@ViewBuilder
var destinationView: some View {
switch self {
case .view1:
CarView()
case .view2:
HouseView()
case .view3:
MusicView()
case .view4:
ShoesView()
case .view5:
BooksView()
}
}
}
Once again, would really appreciate someone to help and many thanks 🙏!