繁体   English   中英

TabBar SwiftUI 2.0 中其他视图的键盘调用 OnAppear

[英]Keyboard Calls OnAppear of Other Views in TabBar SwiftUI 2.0

我在 SwiftUI 2.0 和 Xcode 12 中使用 UITabBarController,但似乎键盘盒出现了一些意外行为。 正如您从下面的 GIF 中看到的,当键盘出现在第一个选项卡中时,调用了其他 2 个选项卡视图的 OnAppear。 这导致了这个问题,因为我有一个写在上面的 API 调用出现。

另外,有什么方法可以关闭 Xcode 12 的默认视图偏移行为。

在此处输入图片说明

这是我的内容视图代码。

struct ContentView: View {
    @State private var index:Int = 0
    var menuItems:[String] = ["Item 1", "Item 2", "Item 3"]
    var body: some View {
        NavigationView(content: {
            ZStack{
                MyTabView(selectedIndex: self.$index)
                    .view(item: self.item1) {
                        NewView(title: "Hello1").navigationBarTitle("")
                            .navigationBarHidden(true)
                    }
                    .view(item: self.item2) {
                        NewView(title: "Hello2").navigationBarTitle("")
                            .navigationBarHidden(true)
                    }
                    .view(item: self.item3) {
                        NewView(title: "Hello3").navigationBarTitle("")
                            .navigationBarHidden(true)
                    }
            }.navigationBarHidden(true)
            .navigationBarTitle("")
        })
    }
    
    var item1:MyTabItem {
        
        var item = MyTabItem()
        item.imageName = "pencil.circle"
        item.selectedImageName = "pencil.circle.fill"
        return item
    }
    
    var item2:MyTabItem {
        var item = MyTabItem()
        item.imageName = "pencil.circle"
        item.selectedImageName = "pencil.circle.fill"
        return item
    }
    
    var item3:MyTabItem {
        var item = MyTabItem()
        item.imageName = "pencil.circle"
        item.selectedImageName = "pencil.circle.fill"
        return item
    }
}


struct NewView:View {
    @State var text:String = ""
    var title:String
    var body: some View {
        VStack {
            Spacer()
            Text("Hello")
            TextField(title, text: self.$text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
        }.padding()
        .onAppear {
            debugPrint("OnApper \(self.title)")
        }
    }
}

这是 CustomTabView 的代码。

class MyTabViewViewModel:ObservableObject {
    var controllers: [UIViewController] = []
    var tabItems:[MyTabItem] = []
}

struct MyTabItem {
    var imageName:String = ""
    var selectedImageName:String = ""
    var hasDarkModeSupport:Bool = true
    var image:UIImage?
    var selectedImage:UIImage?
}

struct MyTabView: UIViewControllerRepresentable {
    
    var viewModel:MyTabViewViewModel = MyTabViewViewModel()
    
    @Binding var selectedIndex: Int
    
    func makeUIViewController(context: Context) -> UITabBarController {
        let tabBarController = UITabBarController()
        tabBarController.viewControllers = self.viewModel.controllers
        tabBarController.delegate = context.coordinator
        tabBarController.selectedIndex = 0
        
        let appearance = tabBarController.tabBar.standardAppearance
        appearance.shadowImage = nil
        appearance.shadowColor = nil
        appearance.backgroundEffect = nil
        tabBarController.tabBar.standardAppearance = appearance
        
        tabBarController.tabBar.shadowImage = UIImage()
        tabBarController.tabBar.backgroundImage = UIImage()
        tabBarController.tabBar.layer.shadowPath = UIBezierPath(rect: tabBarController.tabBar.bounds).cgPath
        tabBarController.tabBar.layer.shadowOffset = CGSize.init(width: 0, height: -3)
        tabBarController.tabBar.layer.shadowRadius = 5
        tabBarController.tabBar.layer.shadowColor = UIColor.black.cgColor
        tabBarController.tabBar.layer.shadowOpacity = 0.25
        tabBarController.tabBar.backgroundColor = UIColor.white
        tabBarController.tabBar.barTintColor = UIColor.white
        
        self.updateTabItems(forTabBarController: tabBarController)
        
        return tabBarController
    }
    
    func updateUIViewController(_ tabBarController: UITabBarController, context: Context) {
        tabBarController.selectedIndex = selectedIndex
        self.updateTabItems(forTabBarController: tabBarController)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    func updateTabItems(forTabBarController tabBarController:UITabBarController) {
        let isDarkModeEnable:Bool = tabBarController.traitCollection.userInterfaceStyle == .dark
        for (index, tabItem) in self.viewModel.tabItems.enumerated() {
            
            tabBarController.tabBar.items?[index].title = ""
            
            if let image = tabItem.image {
                tabBarController.tabBar.items?[index].image = image
                if let selectedImage = tabItem.selectedImage {
                    tabBarController.tabBar.items?[index].selectedImage = selectedImage
                }
            } else {
                if tabItem.hasDarkModeSupport && isDarkModeEnable {
                    if let image = UIImage.init(systemName: "\(tabItem.imageName)-dark") {
                        tabBarController.tabBar.items?[index].image = image
                    } else if let image = UIImage.init(systemName: tabItem.imageName) {
                        tabBarController.tabBar.items?[index].image = image
                    }
                    if let selectedImage = UIImage.init(systemName: "\(tabItem.selectedImageName)-dark") {
                        tabBarController.tabBar.items?[index].selectedImage = selectedImage
                    } else if let selectedImage = UIImage.init(systemName: tabItem.selectedImageName) {
                        tabBarController.tabBar.items?[index].selectedImage = selectedImage
                    }
                } else {
                    if let image = UIImage.init(systemName: tabItem.imageName) {
                        tabBarController.tabBar.items?[index].image = image
                    }
                    if let selectedImage = UIImage.init(systemName: tabItem.selectedImageName) {
                        tabBarController.tabBar.items?[index].selectedImage = selectedImage
                    }
                }
            }
        }
    }
    
    class Coordinator: NSObject, UITabBarControllerDelegate {
        var parent: MyTabView
        
        init(_ tabBarController: MyTabView) {
            self.parent = tabBarController
        }
        
        func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
            parent.selectedIndex = tabBarController.selectedIndex
        }
    }
    
    func view<HostedView:View>(item:MyTabItem, @ViewBuilder sheet: @escaping () -> HostedView) -> MyTabView {
        self.viewModel.controllers.append(UIHostingController.init(rootView: sheet()))
        self.viewModel.tabItems.append(item)
        return self
    }
}

我自己也有同样的问题

“黑客”解决方法是将NewView.body包装在一个列表中:

    @State var text:String = ""
    var title:String
    var body: some View {
        List {
            VStack {
                Spacer()
                Text("Hello")
                TextField(title, text: self.$text)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                
            }.padding()
            .onAppear {
                debugPrint("OnApper \(self.title)")
            }
        }
    }
}

也可以使用LazyVStack ,但由于我的项目目标是LazyVStack ,因此还没有对其进行测试

同样的问题当键盘出现在 SwiftUI 中时 OnAppear 意外调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM