75142913在线留言
【SwiftUI实战】子视图里隐藏TabBar的几种方式_IOS开发_网络人

【SwiftUI实战】子视图里隐藏TabBar的几种方式

Kwok 发表于:2022-02-25 10:25:11 点击:131 评论: 0

在使用SwiftUI内置组件里TabView是一个很强大的存在,方便实用,可惜扩展性和可定义性太差了,我们通常很难修改其样式。包括在不需要显示的特殊视图无法将其有效的隐藏,下面我总结几个我使用的临时处理方案。

一、iOS 14将NavigationView做为父级

将NavigationView放到TabView的上级,这样使用NavigationLink跳转到的子视图就可以实现将TabBar隐藏的效果:

NavigationView {
   TabView(selection: $selectedTab) {
      //TabBar项
   }
}.navigationViewStyle(StackNavigationViewStyle())//iPad、Mac上的样式统一

这个方案一直用得好好的,直到升级了iOS15后,发现存在了部分的问题,如同时返回多个视图,最严重的是当前子视图的情况下 切换到后台 再回到APP就会立即返回到 NavigationView 级视图,这个问题困扰了我很久,调试了几天才发现 因为NavigationView嵌套导致的。底层原因目前还不知道。

二、使用ZSsack 

这个方案可以在使用调用相机、或者登陆页等,全屏页使用:

ZStack {
   TabView(selection: $selectedTab) {
      //TabBar项
   }
   if true{
       FullView()//使用覆盖原理遮住TabBar
   }
}

这里只提供了思路,因为可能出现向下不断Binding的情况,维护起来极为不便。

三、使用隐藏代码(修改器)

.opacity(hideTabBar == true ? 0 : 1)//将其透明
UITabBar.appearance().isHidden = true //初始化时设置状态为隐藏 .onAppear() 

在当前视图可以隐藏,但在子视图里并不能调用修改。所以这个方法也基本无效。

四、修改底层代码重建视图

我们看到第三项可以使用isHidden来控制TabBar的显示状态,现在我们扩展一个修饰器来实现:

extension UIApplication {
    var key: UIWindow? {
        self.connectedScenes
            .map({$0 as? UIWindowScene})
            .compactMap({$0})
            .first?
            .windows
            .filter({$0.isKeyWindow})
            .first
    }
}
//扩展底层的UIView 以获取到TabBar属性
extension UIView {
    func allSubviews() -> [UIView] {
        var subs = self.subviews
        for subview in self.subviews {
            let rec = subview.allSubviews()
            subs.append(contentsOf: rec)
        }
        return subs
    }
}
//修改TabBar
struct TabBarModifier {
    static func showTabBar() {
        UIApplication.shared.key?.allSubviews().forEach({ subView in
            if let view = subView as? UITabBar {
                view.backgroundColor = .systemGray5 //BUGS: 后台驻足时间够长,返回时TabBar无背景
                view.barTintColor = .systemBackground//BUGS: 后台驻足时间够长,返回时TabBar无背景
                view.isHidden = false //将TabBar隐藏
            }
        })
    }
    
    static func hideTabBar() {
        UIApplication.shared.key?.allSubviews().forEach({ subView in
            if let view = subView as? UITabBar {
                view.isHidden = true//显示 TabBar
            }
        })
    }
}
//使用 ViewModifier 显示TabBar
struct ShowTabBar: ViewModifier {
    func body(content: Content) -> some View {
        return content.padding(.zero).onAppear {
            TabBarModifier.showTabBar()
        }
    }
}
//同上 隐藏TabBar
struct HiddenTabBar: ViewModifier {
    func body(content: Content) -> some View {
        return content.padding(.zero).onAppear {
            TabBarModifier.hideTabBar()
        }
    }
}
//方便调用
extension View {
    var showTabBar:some View {
        return self.modifier(ShowTabBar())
    }
    var hiddenTabBar:some View {
        return self.modifier(HiddenTabBar())
    }
}

使用方式:在需要显示的视图上调用.showTabBar,在要隐藏的视图上调用.hiddenTabBar即可

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/196
标签:TabBarKwok最后编辑于:2022-02-25 10:25:46
1
感谢打赏!

《【SwiftUI实战】子视图里隐藏TabBar的几种方式》的网友评论(0)

本站推荐阅读

热门点击文章