ios 尝试隐藏选项卡栏SwiftUI时出现问题

bqucvtff  于 2023-02-17  发布在  iOS
关注(0)|答案(2)|浏览(140)

有几个类似的问题。有一个小的差异,我没有注意到在任何其他答案。基本上我有一个TabView和它的每一个项目是 Package 在NavigationView。因为它是这样做的,而不是相反的方式围绕第一个NavigationViewTabView的方式隐藏视图并不那么简单。

extension UIView {
    func allSubviews() -> [UIView] {
        var allSubviews = subviews
        for subview in subviews {
            allSubviews.append(contentsOf: subview.allSubviews())
        }
        return allSubviews
    }
}

extension UITabBar {
    private static var originalY: Double?
    
    static public func changeTabBarState(shouldHide: Bool) {
        let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
        windowScene?.windows.first(where: { $0.isKeyWindow })?.allSubviews().forEach({ view in
            if let tabBar = view as? UITabBar {
                if !tabBar.isHidden && shouldHide {
                    originalY = tabBar.frame.origin.y
                    tabBar.frame.origin.y = UIScreen.main.bounds.height + 200
                } else if tabBar.isHidden && !shouldHide {
                    guard let originalY else {
                        return
                    }
                    tabBar.frame.origin.y = originalY
                }
                tabBar.isHidden = shouldHide
            }
        })
    }
}

struct MyTabView: View {
    @Environment(\.colorScheme) var colorScheme
    @State var toggle = false
    
    var body: some View {
        TabView {
            NavigationView {
                ContentView(toggle: $toggle)
            }
            .tabItem {
                Text("Profile")
                    .foregroundColor(colorScheme == .dark ? .white : .black)
            }
        }
        .accentColor(colorScheme == .dark ? .white : .black)
        .navigationBarTitleDisplayMode(.inline)
    }
}

struct ContentView: View {
    @Binding var toggle: Bool
    
    var body: some View {
        NavigationLink(isActive: $toggle, destination: {
            Button("dismiss") {
                UITabBar.changeTabBarState(shouldHide: false)
                toggle.toggle()
            }
            .navigationBarBackButtonHidden()
            .navigationBarHidden(true)
            .onAppear {
                UITabBar.changeTabBarState(shouldHide: true)
            }
        }, label: {
            Text("Click")
        })
    }
}

@main
struct AppTestingOne: App {
    var body: some Scene {
        WindowGroup {
            MyTabView()
        }
    }
}

当我这样做时,我得到的问题如下。当我点击第一个屏幕上的按钮时,我被发送到这里:

初看起来似乎没什么问题。事实上,按钮dismiss就像底部的一个隐形填充。有趣的是,当我旋转到横向回到全屏时,这个填充消失了。

当你看这些图片时,似乎没有问题,但当你在顶部和底部有东西时,当你重新旋转它时,它会被推高并固定。

mfuanj7w

mfuanj7w1#

如果您正在为iOS 16进行构建,则只需使用

.toolbar(.hidden, for: .tabBar)

示例:

struct ContentView: View {
    
    var body: some View {
        TabView() {
            FirstScreen()
            
            NavigationStack {
                Text("second")
                    .navigationTitle("second")
            }
            .tabItem {
                Label("second", systemImage: "2.circle")
            }
            NavigationStack {
                Text("third")
                    .navigationTitle("third")
            }
            .tabItem {
                Label("third", systemImage: "3.circle")
            }
        }
    }
}

struct FirstScreen: View {
    
    @State private var hideTabBar = false
    
    var body: some View {
        NavigationStack() {
            VStack {
                Button("Toggle tab bar") {
                    withAnimation {
                        hideTabBar.toggle()
                    }
                }
                .padding()
                Spacer()
            }
            .navigationTitle("first")
        }
        .toolbar(hideTabBar ? .hidden : .visible, for: .tabBar)
        .tabItem {
            Label("first", systemImage: "1.circle")
        }
    }
}

kcrjzv8t

kcrjzv8t2#

我发现了一个非常酷的解决方案。当我隐藏tabBar时,我可以根据手机的不同向下推它的超级视图(公式需要计算),旋转后,它继续工作,忽略我推了多少,回到它应该的样子,因为我为iPhone12,13,14计算了它,它工作得一样好。

extension UIView {
    func allSubviews() -> [UIView] {
        var allSubviews = subviews
        for subview in subviews {
            allSubviews.append(contentsOf: subview.allSubviews())
        }
        return allSubviews
    }
}

extension UITabBar {
    private static var originalY: Double?
    
    static public func changeTabBarState(shouldHide: Bool) {
        let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
        windowScene?.windows.first(where: { $0.isKeyWindow })?.allSubviews().forEach({ view in
            if let tabBar = view as? UITabBar {
                if !tabBar.isHidden && shouldHide {
                    originalY = (tabBar.superview?.frame.origin.y)!
                    tabBar.superview?.frame.origin.y = (tabBar.superview?.frame.origin.y)! + 4.5
                } else if tabBar.isHidden && !shouldHide {
                    guard let originalY else {
                        return
                    }
                    tabBar.superview?.frame.origin.y = originalY
                }
                tabBar.isHidden = shouldHide
                tabBar.superview?.setNeedsLayout()
                tabBar.superview?.layoutIfNeeded()
            }
        })
    }
}

struct MyTabView: View {
    @Environment(\.colorScheme) var colorScheme
    @State var toggle = false
    
    var body: some View {
        TabView {
            NavigationView {
                RandomView(toggle: $toggle)
            }
            .tabItem {
                Text("Profile")
                    .foregroundColor(colorScheme == .dark ? .white : .black)
            }
        }
        .accentColor(colorScheme == .dark ? .white : .black)
        .navigationBarTitleDisplayMode(.inline)
    }
}

struct RandomView: View {
    @Binding var toggle: Bool
    
    var body: some View {
        NavigationLink(isActive: $toggle, destination: {
            Button("dismiss") {
                UITabBar.changeTabBarState(shouldHide: false)
                toggle.toggle()
            }
            .navigationBarBackButtonHidden()
            .navigationBarHidden(true)
            .onAppear {
                UITabBar.changeTabBarState(shouldHide: true)
            }
        }, label: {
            Text("Click")
        })
    }
}

@main
struct AppTestingTwo: App {
    var body: some Scene {
        WindowGroup {
            MyTabView()
        }
    }
}

相关问题