SwiftUI NavigationSplitView在应用移到后台时丢失工具栏按钮- iOS 17 / Xcode 15.0

gupuwyp2  于 12个月前  发布在  iOS
关注(0)|答案(1)|浏览(121)

iPadOS 17上的SwiftUI NavigationSplitView在应用程序移动到后台并返回到前台时会松开侧边栏中的工具栏按钮。它不会发生在iOS 17上的iPhone 15 Plus的横向模式。这不会发生在NavigationStack上。

@main
struct EditModeMoveToBackgroundApp: App {
    var body: some Scene {
        WindowGroup {
            NavigationSplitView(columnVisibility: .constant(.all)) {
                ContentView()
            } detail: {
                Text("Detail View")
            }
        }
    }
}

struct ItemStore: Identifiable, Hashable {
    var id = UUID()
    var name: String
}

struct ContentView: View {
    var itemArray = ["Mountain", "River", "Village"].map { ItemStore(name: $0) }
    @Environment(\.editMode) private var editMode
    @State var selection: Set<ItemStore.ID> = []
    
    var body: some View {
        List(selection: $selection) {
            ForEach(itemArray) { item in
                Text(item.name)
            }
        }
        .toolbar {
            EditButton()
        }
    }
}

这是一个严重的错误,因为它将用户锁定在编辑模式中,用户只能通过再次冷启动应用程序来摆脱。
有人知道解决方案/解决方案吗?
另一个不太严重的bug也存在:用户需要点击编辑按钮两次以激活编辑模式。

wko9yo5t

wko9yo5t1#

我的解决方法是在应用程序处于非活动状态时从工具栏中删除编辑按钮,并在应用程序再次处于活动状态时再次显示该按钮:

var body: some Scene {
WindowGroup {
    MainView()
        .onChange(of: scenePhase) { scenePhase in

            switch scenePhase {

            case .background:
                print(".background")

            case .inactive:

                state.showToolbarItems = false
                state.editMode = .inactive

            case .active:

                state.showToolbarItems = true

            @unknown default:
                print("unknown scenePhase")
                fatalError()
            }
        }
    }
}

在定义工具栏项的视图中,将其包含在if语句中:

.toolbar {
    if state.showToolbarItems {
            
    ToolbarItemGroup(placement: .primaryAction) {
            CustomEditButton(editMode: $state.editMode)
        }
    }
}

关于另一个bug -需要点击按钮两次才能激活编辑模式-我通过使用自定义的编辑模式按钮来解决这个bug:

struct CustomEditButton: View {
@Binding var editMode: EditMode

var cleanUpAction: () -> Void = {}
var prepareEditMode: () -> Void = {}

var body: some View {
    Button {
        withAnimation {
            if editMode == .active {
                editMode = .inactive
                cleanUpAction()
            } else {
                editMode = .active
                prepareEditMode()
            }
        }
    } label: {
        if editMode == .active {
            Text("Done").bold()
        } else {
            Text("Edit")
        }
    }
}

这是上面引用的状态类,我在视图中用作ObservedObject:

class AppState: ObservableObject {
    static var shared = AppState()
    init() { }
    
    @Published var editMode: EditMode = .inactive
    @Published var showToolbarItems: Bool = true
}

相关问题