ios - SwiftUI 在 TabView 中禁用特定的 tabItem 选择?

标签 ios swift swiftui tabview tabitem

我有一个 TabView,它在点击 [+](第二个)tabItem 后显示一个工作表。同时,ContentView 也在切换 TabView 的选项卡选择,所以当我关闭显示的工作表时,所选选项卡是空白的,没有任何内容。不是理想的用户体验。

我的问题:

我想知道如何才能简单地禁用该特定的 tabItem,这样它就不会“表现得像一个选项卡”,而只是呈现工作表,同时在点击 [+ 之前保持之前的选项卡选择] 元素。这对 SwiftUI 来说可能吗?还是我应该通过另一种方式来实现这种效果?

我的标签栏图片:

enter image description here

这是我的 ContentView 的代码,其中我的 TabView 是:

struct SheetPresenter<Content>: View where Content: View {
    @EnvironmentObject var appState: AppState
    @Binding var isPresenting: Bool

    var content: Content
    var body: some View {
        Text("")
            .sheet(isPresented: self.$isPresenting, onDismiss: {
                // change back to previous tab selection
                print("New listing sheet was dismissed")

            }, content: { self.content})
            .onAppear {
                DispatchQueue.main.async {
                    self.isPresenting = true
                    print("New listing sheet appeared with previous tab as tab \(self.appState.selectedTab).")
                }
            }
    }
}

struct ContentView: View {
    @EnvironmentObject var appState: AppState
    @State private var selection = 0
    @State var newListingPresented = false

    var body: some View {

        $appState.selectedTab back to just '$selection'
        TabView(selection: $appState.selectedTab){

            // Browse
            BrowseView()
                .tabItem {
                    Image(systemName: (selection == 0 ? "square.grid.2x2.fill" : "square.grid.2x2")).font(.system(size: 22))
                }
                .tag(0)


            // New Listing
            SheetPresenter(isPresenting: $newListingPresented, content: NewListingView(isPresented: self.$newListingPresented))
                .tabItem {
                    Image(systemName: "plus.square").font(.system(size: 22))
                }
                .tag(1)

            // Bag
            BagView()
                .tabItem {
                    Image(systemName: (selection == 2 ? "bag.fill" : "bag")).font(.system(size: 22))
                }
                .tag(2)

            // Profile
            ProfileView()
                .tabItem {
                    Image(systemName: (selection == 3 ? "person.crop.square.fill" : "person.crop.square")).font(.system(size: 22))
                }
                .tag(3)
        }.edgesIgnoringSafeArea(.top)
    }
}

这是AppState:

final class AppState: ObservableObject {

    @Published var selectedTab: Int = 0
}

最佳答案

您非常接近您想要实现的目标。您只需要保留先前选定的选项卡索引,并在关闭工作表时使用该保留值重置当前选定的选项卡索引。这意味着:

.sheet(isPresented: self.$isPresenting, onDismiss: {
    // change back to previous tab selection
    self.appState.selectedTab = self.appState.previousSelectedTab
}, content: { self.content })

那么如何跟踪与 AppStateselectedTab 属性保持同步的最后选定的选项卡索引?使用 Combine 框架本身的 API 可能有更多方法可以做到这一点,但我想到的最简单的解决方案是:

final class AppState: ObservableObject {
    // private setter because no other object should be able to modify this
    private (set) var previousSelectedTab = -1 
    @Published var selectedTab: Int = 0 {
        didSet {
            previousSelectedTab = oldValue
        }
    }
}

注意事项:

上述解决方案可能与禁用特定选项卡项选择不完全相同,但在您关闭工作表后,它会恢复为选定的舒缓动画呈现工作表之前的选项卡。 <强> Here is the result .

关于ios - SwiftUI 在 TabView 中禁用特定的 tabItem 选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59549000/

相关文章:

swift - 如何从镜像中获取具有空值的标签

ios - 对 SwiftUI FetchRequest 的更改未触发 View 刷新?

ios - 使用Autolayout为对象设置缩放规则

ios - Swift:打开 "in menu"选项

iOS 8 - 服务器 'randomly' 未接收到使用 tcp/ip 协议(protocol)发送的数据包

ios - 结构中的 Swift Init 可选数组

ios - 测试设备上的结果始终为 100

swift - 在 MongoDB Realm 中终止并重新启用同步后,我必须在客户端删除哪个文件?

SwiftUI TextField 简单示例不起作用

ios - SwiftUI TextEditor 初始内容大小错误