Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么swift视图不使用UIKit更新?_Swift_Swiftui_Uikit_Tabbar - Fatal编程技术网

为什么swift视图不使用UIKit更新?

为什么swift视图不使用UIKit更新?,swift,swiftui,uikit,tabbar,Swift,Swiftui,Uikit,Tabbar,我有带动画的swiftUI选项卡栏,还有包含此swiftUI视图的UITabbarViewController 迅捷 struct MainTabBarView: View { @ObservedObject var viewModel: MainTabBarViewModel var body: some View { VStack { HStack(spacing: 0) { TabItem(curr

我有带动画的swiftUI选项卡栏,还有包含此swiftUI视图的UITabbarViewController

迅捷

struct MainTabBarView: View {
    
    @ObservedObject var viewModel: MainTabBarViewModel
    
    var body: some View {
        VStack {
        HStack(spacing: 0) {
            TabItem(currentIndex: $viewModel.index, tabIndex: 0, tab: .home)
            Spacer()
            TabItem(currentIndex: $viewModel.index, tabIndex: 1, tab: .search)
            Spacer()
            TabItem(currentIndex: $viewModel.index, tabIndex: 2, tab: .library)
        }.padding(.top, 8).padding(.leading, 28).padding(.trailing, 28)
        .padding(.bottom, 8)
        .frame(width: UIScreen.main.bounds.width)
        .animation(.easeIn(duration: 0.2))

}
UITABBARVIEW控制器:

final class MainTabBarViewController: UITabBarController, Navigatable {
         private var viewModel = MainTabBarViewModel()

        // MARK: - Lifecycle
        override func viewDidLoad() {
            super.viewDidLoad()
            bindViewModel()
        }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configTabBarView()
    }
 
     
        private func configTabBarView() {
            let view = UIHostingController(rootView: MainTabBarView(viewModel: viewModel))
            addChild(child)
            tabBar.addSubview(view.view)
            view.didMove(toParent: self)
            tabBar.setValue(true, forKey: "hidesShadow")
            view.view.snp.makeConstraints { make in
                make.leading.trailing.top.equalToSuperview()
                make.height.equalTo(100)
            }
         
        }
 
视图模型:

final class MainTabBarViewModel: NSObject, ObservableObject {
   
   @Published var index: Int = 0 
}
这是带有选项卡的自定义视图的代码。 当我按tab->index from viewModel在该视图中更改,然后

struct TabItem: View {
    
    @Binding var currentIndex: Int
    var tabIndex: Int
    var isCurrentTab: Bool {
        return currentIndex == tabIndex
    }
    
    var tab: Tabs
    
    var body: some View {
        HStack {
            Image(uiImage: tab.icon).resizable().frame(width: 25, height: 25, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                .foregroundColor(isCurrentTab ? R.color.primaryColor()!.swiftUI : R.color.grayScaleDark()!.swiftUI)
            Text(isCurrentTab ? tab.title : "").font(Font(R.font.poppinsRegular(size: 16)! as CTFont))
                .foregroundColor(isCurrentTab ? R.color.primaryColor()!.swiftUI : R.color.grayScaleDark()!.swiftUI)
        }.padding(15)
        .onTapGesture {
            self.currentIndex = tabIndex
           logWarn(String(tabIndex))
        }
        .background(self.tabIndex == currentIndex ? Color(R.color.pink()!) : Color.white)
        .frame(height: 44.0)
        .cornerRadius(22.0)
        .clipped()
    }
    
}

索引正在更改,但选项卡不更新视图的问题。看起来,视图没有更新。

虽然编译给定代码会有帮助,但我认为我已经拼凑出一个解决方案,允许当前索引保留在
MainTabBarViewModel
中,前提是它打算在将来保存其他内容。我还假设
TabItem
应该足够通用,它不必特别依赖于
MainTabVarViewModel

我的想法是在创建
TabItem
时提供当前索引的关键路径。如果不是因为
TabItem
更新了当前索引这一事实,那么就足够简单了。但是,因为它确实更新了它,所以在
ontapsignate
闭包中,编译器抱怨它无法通过键路径进行写入,因为
self
是不可变的。所以我用大卫·惠勒(David Wheeler)召唤鬼魂,尝试通过
TabItem.init
中保存的闭包来完成。。。它不存在,所以添加它是解决方案的一部分

第一个
TabItem
成为通用项:

struct选项卡项:视图{
@ObservedObject变量视图模型:TabBarViewModel
let indexKeyPath:WritableKeyPath
让tapClosure:(Int)->Void
//@Binding var currentIndex:Int
var currentIndex:Int{viewModel[keyPath:indexKeyPath]}
...
init(CurrentIndexinViewModel:TabBarViewModel,在indexKeyPath:WritableKeyPath,tabIndex:Int,tab:Tabs)
{
self.viewModel=viewModel
self.indexKeyPath=indexKeyPath
self.tabIndex=tabIndex
self.tab=tab
self.tapClosure={self.viewModel[keyPath:indexKeyPath]=$0}
}
因此,
TabItem
中的所有内容都将编译(在删除对未提供代码的引用之后),除了
正文中的此位

.ontaps手势{
currentIndex=tabIndex
打印(字符串(选项卡索引))
}
我将其更改为使用在
init
中保存的闭包:

.ontaps手势{
tapClosure(tabIndex)
打印(字符串(选项卡索引))
}
然后在
MainTabBarView
body
中创建一个
TabItem
将从此更改:

TabItem(当前索引:$viewModel.index,tabIndex:0,tab:.home)
对此

TabItem(currentIndexIn:viewModel,at:\.index,tabIndex:0,tab:.home)
由于有太多的代码缺失,我无法编译和测试它,这有点猜测。我剔除缺失的代码只是为了消除错误,所以我可以说,至少这个解决方案可以编译。它需要在实际应用程序中应用和测试,以验证它是否有效


无论如何,假设它确实起作用,这个解决方案仍然允许将索引保留在一个可观察对象中,而不依赖该对象的特定类型。

您缺少了很多必要的代码,以便有人能够测试此结果。我只是想我不熟悉
TabItem
。我熟悉
TabView
。除非
TabItem
是SwiftUI的一个新添加项,并且没有找到它(我只是搜索了一下,结果空手而归),我认为查看它的定义很重要。@ChipJarred这是我自己的观点。我添加了此代码。请看上面,可能我有刷新问题,但它看起来像是同一个代码。您是否添加了一个代码片段,说明如何定义
TabItem
?@ChipJarred我用我的选项卡添加了代码)您能再看一次吗