SwiftUI完成了伸缩式导航栏!好家伙,还不收藏一波~

简介: SwiftUI完成了伸缩式导航栏!好家伙,还不收藏一波~

SwiftUI完成了伸缩式导航栏!好家伙,还不收藏一波~


项目背景

在逛某站的时候,看到一个使用HTMLl+CSS构建一个伸缩式导航栏的案例,觉得蛮有意思。

在客户端开发中,导航栏是必不可少的设计元素之一。但纵观很多国内的App,基本都是最为基础的导航栏,缺乏新意。

在本章中,我们就试试使用SwiftUI构建一个伸缩式导航栏,作为练习。

那么,让我们开始吧。

项目搭建

首先,创建一个新的SwiftUI项目,命名为SwiftUITabView

image.png

收缩视图

样式设计方面,由于我们需要构建一个伸缩式的导航栏,那么需要拆解成伸展式收缩式两种样式效果。

首先我们需要声明一个变量来存储它的状态,示例:

@State var isFold: Bool = false

然后我们来构建收缩时的样式,示例:

// 收起效果
func foldView() -> some View {
    Image(systemName: "list.bullet")
        .font(.system(size: 24))
        .frame(minWidth: 0, maxWidth: 60, minHeight: 0, maxHeight: 60)
        .foregroundColor(.black)
        .background(.white)
        .cornerRadius(30)
        .onTapGesture {
            withAnimation(.spring()) {
                self.isFold.toggle()
            }
        }
}

image.png

上述代码中,我们构建了收缩时的样式视图foldView。除了基本的视图样式外,我们在点击这个按钮视图时,切换isFold的状态。

展开视图

然后时展开视图,展开视图部分有两部分组成,一部分是“关闭”按钮,另一块则是标准的导航栏,我们来构建样式。

首先需要声明一个数组来表明我们导航栏内容,示例:

let menuItems = ["首页", "沸点", "课程", "我的"]

然后再声明一个变量来表示当前选中的导航栏的栏目,示例:

@State var selectedItem = 0

最后,我们创建一个新的视图来完成展开视图的样式部分,示例:

// 展开效果
func unfoldView() -> some View {
    HStack {
        Image(systemName: "xmark")
            .font(.system(size: 24))
            .foregroundColor(.pink)
            .onTapGesture {
                withAnimation(.spring()) {        
                    self.isFold.toggle()
                }
            }
        ForEach(menuItems.indices, id: \.self) { index in
            if index == selectedItem {
                Text(menuItems[index])
                    .font(.system(size: 17))
                    .padding(.horizontal, 15)
                    .foregroundColor(.pink)
            } else {
                Text(menuItems[index])
                    .font(.system(size: 17))
                    .padding(.horizontal, 15)
                    .foregroundColor(.black)
                    .onTapGesture {
                        selectedItem = index
                    }
            }
        }
    }
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 60)
    .background(.white)
    .cornerRadius(30)
    .padding(.horizontal)
}

上述代码中,我们创建了一个展开时的视图unfoldView

然后使用HStack横向视图布局,将一个按钮和导航栏文字内容并排展示,当我们点击“关闭”按钮的时候,切换isFold的状态,以及我们还根据当前点击的index的位置,更新selectedItem选中的栏目,当选中时,我们给选中的栏目设置一个粉色的文字颜色用于区分。

主页视图

完成两个视图后,我们返回ContentView视图,我们根据isFold设置视图,示例:

var body: some View {
    ZStack {
        Color(.systemGray6)
        if isFold {
            unfoldView()
        } else {
            foldView()
        }
    }.edgesIgnoringSafeArea(.all)
}

image.png

效果还不错,只是缺少了过渡动画,整个交互看起来略显生硬。

过渡动画

我们先声明一个变量来存储交换位置的状态,示例:

@Namespace private var Transition

然后使用matchedGeometryEffect修饰符进行位置过渡切换,matchedGeometryEffect修饰符需要修饰两个按钮,示例:

//收起时按钮
Image(systemName: "list.bullet”)
    .matchedGeometryEffect(id: "fold", in: Transition)    
//展开时按钮
Image(systemName: "xmark”)
    .matchedGeometryEffect(id: "fold", in: Transition)

这里如果我们要看到最终的效果,我们需要运行模拟器,在真机环境下才能看到最终的交互效果。

项目预览

image.png

恭喜你,完成了本章的全部内容!

快来动手试试吧。

相关文章
|
11月前
|
Java 容器
膜拜!清华大佬手撸多线程并发源码笔记Github上线3天星标35k+
你为什么要学习多线程?是因为理想吗?是因为热爱吗? 哦~原来是为了面试打基础、做准备啊!没错,这真的很现实!
膜拜!清华大佬手撸多线程并发源码笔记Github上线3天星标35k+
颜值即正义,使用SwiftUI搭建版本更新弹窗
颜值即正义,使用SwiftUI搭建版本更新弹窗
137 0
颜值即正义,使用SwiftUI搭建简历管理详情页
颜值即正义,使用SwiftUI搭建简历管理详情页
71 0
|
存储 XML JSON
简简单单搞一个实用的Android端搜索框
效果很常见,就是平常需求中的效果,上面是搜索框,下面是最近和热门搜索列表,为了方便大家在实际需求中使用,配置了很多属性,也进行了上下控件的拆分,也就是上边搜索框和下面的搜索列表的拆分,可以按需进行使用。
205 0
|
存储 Java API
一个精美的主界面窗口功能的设计和实现原来如此简单,万字肝爆
一个精美的主界面窗口功能的设计和实现原来如此简单,万字肝爆
114 0
|
JavaScript 前端开发 程序员
程序员的未来职场选择;点击按钮发送验证码怎么显得水平高;自学 VUE ,可以直接做项目吗|极客观点
程序员的未来职场选择;点击按钮发送验证码怎么显得水平高;自学 VUE ,可以直接做项目吗|极客观点
|
存储 数据库 开发者
第五课(三)|学习笔记
快速学习第五课(三)
141 0
第五课(三)|学习笔记
|
关系型数据库 数据库 开发者
第五课(二)|学习笔记
快速学习第五课(二)
102 0
第五课(二)|学习笔记
|
小程序 API Android开发
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
166 0
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
|
数据可视化 uml UED
从 keynote 大神到语雀画图大神,她是怎么做的?
在语雀用户中有这样一位画图达人:一张图就能把项目盘点的清清楚楚,成为对焦项目进度的沟通工具;一张图就能把业务分析的明明白白,让项目成员快速达成共识;一张图就能把知识库的文档呈现得一目了然,帮助看的人快速获取信息。
下一篇
无影云桌面