75142913在线留言
【SwiftUI实战】segmented分段切换视图的几种方案_IOS开发_网络人

【SwiftUI实战】segmented分段切换视图的几种方案

Kwok 发表于:2021-05-27 09:27:46 点击:77 评论: 0

一开始我想到的是方案是使用switch选择视图进行显示,并且利用手势和动画也可以达到想要的效果,后来发现还可以利用TabView来实现自带的滑动切换视图效果。当然我在网上还看到了利用偏移把其它视图挤出屏幕外的方案。在本文里会慢慢收集更多更好的方案供参考。

2021.10.12 : 最后又写了一个改进版本带动画效果的视图切换,可以参考:http://www.55mx.com/ios/165.html

一、利用switch选择视图切换

struct Index:View {
    private let segmented = ["关注","推荐","食材","精选","家常菜"]
    @State private var selector = 1 //根据segmented的索引值选择视图
    var body: some View{
        VStack{
            //分段切换视图
            HStack{
                ForEach(segmented, id: .self) { name in
                    Button(action: {
                        if let index = segmented.firstIndex(of: name){
                            withAnimation {
                                selector = index //选择视图
                            }
                        }
                    }, label: {
                        //顶部切换文本显示样式
                        if selector == segmented.firstIndex(of: name){
                            Text(name)
                                .font(.system(size: 18, weight: .bold))
                                .overlay(Rectangle().frame(height: 2).offset(y: 4) ,alignment: .bottom)
                                .foregroundColor(.red)
                        }else{
                            Text(name)
                                .foregroundColor(.black)
                        }
                    })
                }
            }
            .padding()
            //根据selector分段切换视图
            ScrollView{
                switch selector{
                    case 1:
                        RecommendedView()//推荐(默认显示此项)
                    case 2:
                        FoodView()//食材
                    case 3:
                        SelectView()//精选
                    case 4:
                        DailyCookView()//家常菜
                    default:
                        FocusView()//不匹配的情况下显示
                }
            }
            .offset(x:gesturePanOffset.width)
            .gesture(panGesture())//拖动手势(切换View)
//            .transition(.slide)
//            .animation(.easeInOut)
            .navigationBarHidden(true) //隐藏包括标题和返回键在内的所有系统导航栏
            .navigationBarBackButtonHidden(true)//只隐藏系统导航栏中的返回键
        }
    }    
    //平移手势
    @GestureState private var gesturePanOffset:CGSize = .zero //手势结束会恢复初值
    //手势定义
    private func panGesture() -> some Gesture{
        DragGesture()
            //有空仔细学一下updating到底在做什么
            .updating($gesturePanOffset){ lastestGestureValue, gesturePan, animation in
                gesturePan = lastestGestureValue.translation //gesturePan的更新会影响$gesturePanOffset的值变化
                animation.animation = .easeInOut//拖动的动画处理
            }
            //手势结束后的操作(循环切换分段View)
            .onEnded{ value in
                let moveOffset = UIScreen.main.bounds.width / 2 //超过屏幕宽度(计算后的值)才发生偏移
                let lastIndex = segmented.endIndex - 1//数组最后一个索引值
                //向右拖动
                if value.translation.width > moveOffset{
                    if selector <= 0{
                        selector = lastIndex
                    }else{
                        selector -= 1
                    }
                }
                //向左拖动
                if -value.translation.width > moveOffset{
                    if selector >= lastIndex {
                        selector = 0
                    }else{
                        selector += 1
                    }
                }
            }
    }
}

SwiftUI实战segmented分段切换视图的几种方案

二、利用TabView实现上面一样的功能

    @State private var selector = Segmented.recommended //根据segmented的索引值选择视图    
    enum Segmented: String,CaseIterable {
        case focus = "关注",recommended = "推荐", food = "食材", select = "精选", dailyCook = "家常菜"
    }
    var body: some View{
        VStack{
            //分段切换视图
            HStack{
                ForEach(Segmented.allCases ,id: .self){ name in
                    Button(action: {
                        withAnimation {
                            selector = name
                        }
                    }, label: {
                        if selector == name{
                            Text(name.rawValue)
                                .font(.system(size: 18, weight: .bold))
                                .overlay(Rectangle().frame(height: 2).offset(y: 4) ,alignment: .bottom)
                                .foregroundColor(.red)
                        }else{
                            Text(name.rawValue)
                                .foregroundColor(.black)
                        }
                        
                    })
                }
                
            }
            .padding(.top)
            TabView(selection: $selector) {
                FocusView().tabItem{}.tag(Segmented.focus)
                RecommendedView().tabItem{}.tag(Segmented.recommended)
                FoodView().tabItem{}.tag(Segmented.food)
                SelectView().tabItem{}.tag(Segmented.select)
                DailyCookView().tabItem{}.tag(Segmented.dailyCook)
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))//不显示切换文字
            .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))//不显示背景
        }
    }

这里由于去掉了自己定义的手势代码,切换选择使用了枚举,所以代码看上去更精简一些。可以根据自己喜欢选择。

TabView还可以切换很多视图,关于介绍可以参考:http://www.55mx.com/ios/127.html

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/142
标签:分段SwiftUITabViewKwok最后编辑于:2021-10-12 12:12:46
0
感谢打赏!

《【SwiftUI实战】segmented分段切换视图的几种方案》的网友评论(0)

本站推荐阅读

热门点击文章