75142913在线留言
【SwiftUI实战】利用LazyVStack的onAppear与onDisappear特性制作无限联动分类_IOS开发_网络人

【SwiftUI实战】利用LazyVStack的onAppear与onDisappear特性制作无限联动分类

Kwok 发表于:2021-11-19 11:19:31 点击:0 评论: 0

LazyVStack具有每次进入屏幕调用onAppear,离开屏幕调用onDisappear的功能,意味为将LazyVStack放到ScrollView以后,只要用户滚动视图就可以一直触发功能代码。

我们可以利用LazyVStack的这2个特性制作一个无限联动的分类菜单。这也是目前我使用的最成熟的一种方案了,经过暴力测试,完全符合我的预期需求。推荐大家使用。

一、代码分步实现

1、首先我们要定义2个临时的外部状态变量:

@State var ScrollVal = "" //当前的分类默认为空
@State var setTypes = Set()//存放分类的集合

2、将视图分为2栏

var body: some View{
    ScrollViewReader { scrollProxy in//锚点跳转雷达
        HStack(spacing:0){
                //左侧遍历的所“顶级分类”点击scrollTo
            ScrollView(.vertical, showsIndicators: false){
                VStack(spacing:0){
                    ForEach(catData.cates){ cat in //遍历左侧显示的主分类
                        catScrollTo(categorie:cat, scrollProxy: scrollProxy)
                        .id(cat.type)//用type字段做为锚点,联动跳转的关键
                    }
                }
            }.frame(width: 110)//左侧宽度根据自己的情况调整

            Divider()//分栏线

            ScrollView(.vertical,showsIndicators: false){
                LazyVStack{
                    ForEach(catData.cates){ cat in //遍历右边显示的主分类下的子分类内容
                        typeView(cat: cat.children, type: cat.type)
                            .id(cat.typename)//使用名称做为锚点,联动跳转的到指定位置
                    }
                }
            }
        }
    }.animation(.spring(), value: ScrollVal)//统一使用这个动画效果
}

3、左侧主分类展示的子视图

func catScrollTo(categorie:FoodTypeModel,scrollProxy:ScrollViewProxy) -> some View{
    VStack(spacing:0){
        Text(categorie.typename)
            .modifier(CatScrollStyle(isIDEqual: ScrollVal == categorie.type))
            .onTapGesture{
                scrollProxy.scrollTo(categorie.typename,anchor: .top) //点击后将右边对应锚点的顶部
            }            
    }
}

我们还有一个分类展示的modifier,传入一个布尔值,当被选中或者滚动到对应位置时显示不同的样式。

    //分类样式
private struct CatScrollStyle: ViewModifier{
    let isIDEqual:Bool
    func body(content: Content) -> some View {
        ZStack{
            if isIDEqual{ Color.gray.opacity(0.1).overlay(Color.red.opacity(0.8).frame(width:3), alignment: .leading) }
            content.foregroundColor(isIDEqual ? .red : .black.opacity(0.8)).padding(18)
        }
    }
}

4、右侧分类里的子分类内容视图

    //Type 顶组分类的的内容视图
func typeView(cat:[FoodTypeModel.Child],type:String)-> some View{
    ForEach(cat){ subCat in//遍历“顶级分类”下的“所有子分类”
        Text(subCat.name).padding(20)
    }
    .onAppear{
        setTypes.insert(type)//显示时将此项加入到集合里
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) { //防止动画惯性(跑多了,又回来1步)
            if let inType = setTypes.first, inType != ScrollVal{
                ScrollVal = type //利用LazyVStack的特性设置当前显示的type值
            }
        }
    }
    .onDisappear{
        setTypes.remove(type)//消失时从集合里删除此项
        if let inType = setTypes.first, inType != type{
            ScrollVal = inType //将type从集合删除后从集合里取出1个做为默认值
        }
    }
}

注意理解最后的 onAppear与onDisappear 这是滚动触发左侧样式联动的关键。

二、效果图

SwiftUI实战利用LazyVStack的onAppear与onDisappear特性制作无限联动分类

点击左侧的时候,右侧内容会滚动到相对应的位置,当右侧滚动到对应位置的时候,左也会联动改变样式。

如果你还需要参考更多的实现可以在这里查看:http://www.neter8.com/ios/169.html

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:http://www.neter8.com/ios/178.html
标签:LazyVStackonAppearonDisappear联动Kwok最后编辑于:2021-11-19 12:19:20
0
感谢打赏!

《【SwiftUI实战】利用LazyVStack的onAppear与onDisappear特性制作无限联动分类》的网友评论(0)

本站推荐阅读

热门点击文章