ios 如何让TabView之外的按钮改变当前的标签?

q43xntqr  于 2023-06-25  发布在  iOS
关注(0)|答案(1)|浏览(111)

在我的代码中,我试图在Home()中创建一个按钮,将选项卡栏更改为Profile。我好像做不到。
我认为最好的方法是@Binding吗?如果是这样,我如何让它与视图模型一起工作(我知道有时不推荐这些,但在这个项目中它们是存在的)?
下面是我的代码:

struct Home: View {
        
    var body: some View {
        
        VStack {
            
    
            Button(action: {
                // change tab to profile here
            }) {
                HStack {
                    Text("See profile")
                        .font(.headline)
                        .foregroundColor(.black)
                    Image(systemName: "chevron.right")
                        .foregroundColor(.black)
                }
            }
        }
    }
}

struct MainPage: View {
    @StateObject var appModel: AppViewModel = .init()
    @Namespace var animation

    var body: some View {
        VStack(spacing: 0) {
            TabView(selection: $appModel.currentTab) {
                Profile()
                    .tag(Tab.Market)
                    .setUpTab()

                Home()
                    .tag(Tab.Home)
                    .setUpTab()

                Statistics()
                    .tag(Tab.Statistics)
                    .setUpTab()

            }
            .overlay(alignment: .bottom) {
                CustomTabBar(currentTab: $appModel.currentTab, animation: animation)
            }
        }
    }
}

enum Tab: String,CaseIterable{
    case Profile = "Profile"
    case Home = "Home"
    case Statistics = "Statistics"
}

struct CustomTabBar: View {
    @Binding var currentTab: Tab
    var animation: Namespace.ID
    // Current Tab XValue...
    @State var currentXValue: CGFloat = 0
    var body: some View {
        HStack(spacing: 0){
            ForEach(Tab.allCases,id: \.rawValue){tab in
                TabButton(tab: tab)
                    .overlay {
                        Text(tab.rawValue)
                            .font(.system(size: 14, weight: .semibold))
                            .foregroundColor(.black)
                            .fixedSize(horizontal: true, vertical: false)
                            .offset(y: currentTab == tab ? 15 : 100)
                    }
            }
        }
        .padding(.top)
        // Preview wont show safeArea...
        .padding(.bottom,getSafeArea().bottom == 0 ? 15 : 10)
        .background{

            Color(.white)
                .shadow(color: .black.opacity(0.08), radius: 5, x: 0, y: -5)
                .clipShape(BottomCurve(currentXValue: currentXValue))
                .ignoresSafeArea(.container, edges: .bottom)
        }
    }
    // TabButton...
    @ViewBuilder
    func TabButton(tab: Tab)->some View{
        // Since we need XAxis Value for Curve...
        GeometryReader{proxy in
            Button {
                withAnimation(.easeInOut){
                    currentTab = tab
                    // updating Value...
                    currentXValue = proxy.frame(in: .global).midX
                }
                
            } label: {
                // Moving Button up for current Tab...
                Image(tab.rawValue)
                // Since we need perfect value for Curve...
                    .resizable()
                    .renderingMode(.template)
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 25, height: 25)
                    .frame(maxWidth: .infinity)
                    .foregroundColor(currentTab == tab ? .white : .gray.opacity(0.8))
                    .padding(currentTab == tab ? 15 : 0)
                    .background(
                        ZStack{
                            if currentTab == tab{
                                Circle()
                                    .fill(.blue)
                                    .shadow(color: .black.opacity(0.1), radius: 8, x: 5, y: 5)
                                    .matchedGeometryEffect(id: "TAB", in: animation)
                            }
                        }
                    )
                    .contentShape(Rectangle())
                    .offset(y: currentTab == tab ? -50 : 0)
            }
            // Setting intial Curve Position...
            .onAppear {
                
                if tab == Tab.allCases.first && currentXValue == 0{
                    
                    currentXValue = proxy.frame(in: .global).midX
                }
            }
        }
        .frame(height: 30)
    }
}
extension View{
    func getSafeArea()->UIEdgeInsets{
        guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{
            return .zero
        }
        
        guard let safeArea = screen.windows.first?.safeAreaInsets else{
            return .zero
        }
        
        return safeArea
    }
}

class AppViewModel: ObservableObject {
       
    @Published var currentTab: Tab = .Home

}

Home()中的按钮如何将选项卡更改为显示Profile()?

jaql4c8m

jaql4c8m1#

struct Home: View {
    @ObservedObject var appModel: AppViewModel // Add this line

    init(appModel: AppViewModel) { // Add this initializer
        self.appModel = appModel
    }

    var body: some View {
            Button(action: {
              appModel.currentTab = .Profile
            }) {
               // Button content...
            }
    }
}

初始化home为

Home(appModel: appModel) // Pass the appModel parameter
    .tag(Tab.Home)
    .setUpTab()

相关问题