75142913在线留言
SwiftUI带动画效果的分段切换视图_IOS开发_网络人

SwiftUI带动画效果的分段切换视图

Kwok 发表于:2021-10-11 16:11:44 点击:68 评论: 0

此效果是由:http://www.55mx.com/ios/142.html改进而来的,可以参考旧的代码。

SwiftUI带动画效果的分段切换视图

当用户点击或者滑动时将会切换视图,开始我使用了固定的参数:

//分段切换视图
struct Segmented:View {
    @State private var selector = Segmented.recommended //根据segmented的索引值选择视图
    //MARK: Bugs 根据选择手动返回偏移量(居中位置开始)
    private var offset:CGFloat{
        switch selector {
            case .focus: return -98
            case .recommended: return -53
            case .food: return -9
            case .select: return 36
            case .dailyCook: return 89
        }
    }
    enum Segmented: String,CaseIterable {
        case focus = "关注",recommended = "推荐", food = "食材", select = "精选", dailyCook = "家常菜"
    }
    var body: some View{
        VStack(spacing:2){
            HStack(spacing:10){
                ForEach(Segmented.allCases ,id: .self){ name in
                    //点击选择要显示的视图
                    Button(action: { withAnimation {
                        selector = name
                    } }){
                        Text(name.rawValue)
                            .modifier(TextFly(isFocus: selector == name))
                    }
                }
            }
            Divider()
                .frame(width: (selector == .dailyCook) ? 55 : 36, height: 2)
                .background(Color.pink)
                .offset(x: offset)
                .animation(.easeInOut(duration: 0.2), value:selector)
            
            //滑动分段切换视图
            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))//不显示背景
        }
    }    
}

虽然在各平台下都可以正常使用,但参数是手动罢黜固定的,不灵活,所以我修改了一下:

//分段切换视图
struct Segmented:View {
    @State private var selector = Segmented.recommended //根据segmented的索引值选择视图
    @Namespace private var selectors //matchedGeometryEffect需要的参数
    enum Segmented: String,CaseIterable {
        case focus = "关注",recommended = "推荐", food = "食材", select = "精选", dailyCook = "家常菜"
    }
    var body: some View{
        VStack(spacing:2){
            HStack(spacing:10){
                ForEach(Segmented.allCases ,id: .self){ name in
                    ZStack(alignment: .bottom){
                        if selector == name{
                            Divider()
                                .frame(width: (selector == .dailyCook) ? 55 : 36, height: 2)
                                .background(Color.pink)
                                .matchedGeometryEffect(id: "top_selectors", in: selectors)
                        }
                        
                        Button{ selector = name } //点击选择要显示的视图
                        label: {
                            Text(name.rawValue)
                                .modifier(TextFly(isFocus: selector == name))
                                .padding(.bottom,3)
                        }
                    }.animation(.spring(), value:selector)//iOS15 新写法
                }
            }
            //滑动分段切换视图
            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))//不显示背景
        }
    }
}

我通过ZStack将Divider()与Text显示在同一维度,并在底部对齐,然后使用.matchedGeometryEffect让动画跨视图播放。这样就可以实现下面红线穿越的效果了。

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

《SwiftUI带动画效果的分段切换视图》的网友评论(0)

本站推荐阅读

热门点击文章