谁说程序员不懂浪漫,教你使用SwiftUI搭建一个电子相册送给她吧~
项目背景
每到七夕情人节、纪念日等节日,身为程序员的我们总是不知道该送什么礼物表达心意,毕竟满脑子装的都是代码。
那我们能不能用代码做一个礼物送给心爱的那个她呢?
即能表达心意,又刚好碰上自己的专业领域。
说干就干。
项目搭建
首先,创建一个新的SwiftUI
项目,命名为ElectronicAlbum
。
素材导入
首先,我们需要导入一堆图片作为展示的素材。我们在Assets.xcassets
文件中导入一批图片,示例:
数据模型
素材导入完成后,接下来我们创建数据模型,我们新增一个Swift
文件,命名为Model.swift
。
import SwiftUI struct Model:Identifiable { var id = UUID() var imageName: String } //示例数据 var models = (1...6).map { Model(imageName:"\($0)") }
上述代码中,我们声明了一个结构体Model
,遵循Identifiable
协议。
在Model
结构体中,我们声明了一个id
作为唯一标识符,然后声明了一个变量imageName
用来关联图片。
在之前我们已经导入了一批图片,并且图片名称为1~6
,因此我们可以声明一个数组models
,通过map
创建示例数据。
页面样式
我们回到ContentView.swift
文件,创建一个新视图来展示图片。示例:
// 图片视图 func imageCardView() -> some View { ForEach(models) { item in Image(item.imageName) .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(10) .padding(.horizontal) .shadow(color: .pink, radius: 5, x: 0, y: 0) } }
上述代码中,我们创建了一个新视图imageCardView
。
在imageCardView
视图中,我们使用ForEach
循环遍历models
数组中的数据,并赋值给Image
图片。
图片样式部分,我们保持图片原有aspectRatio
宽高比,加个cornerRadius
圆角,设置横向padding
边距,最后加了加了一个粉色的边框。
基础交互
页面样式完成后,我们需要左右滚动图片视图,可以使用到TabView
,示例:
var body: some View { TabView { imageCardView() } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) .background(Color(red: 254 / 255, green: 207 / 255, blue: 238 / 255)).edgesIgnoringSafeArea(.all) }
上述代码中,我们在ContentView
视图中使用TabView
构建了一个轮博视图。
我们设置了PageTabViewStyle
样式为隐藏轮播小圆点,然后设置了背景颜色为粉色。
我们预览下效果:
交互进阶
基础交互我们完成基础的轮播图样式,下一步为了让交互更加优雅些,我们可以尝试使用加入些3D切换的效果。
3D切换效果我们需要使用到rotation3DEffect
修饰符,而由于rotation3DEffect
旋转角度接收Double
类型的数值,但我们视图偏移修饰符接收的数值却是CGFloat
类型,因此我们首先声明一个方法进行类型转换和设置旋转交互的角度。
func getAngle(xOffset: CGFloat) -> Double { let tempAngle = xOffset / (UIScreen.main.bounds.width / 2) let rotationDegree: CGFloat = 30 return Double(tempAngle * rotationDegree) }
上述代码中,我们声明了一个方法getAngle
,接收一个CGFloat
类型的参数xOffset
,返回一个Double
类型的参数。
因为我们需要把每个视图展示在中间,因此视图切换角度tempAngle
为屏幕一半来计算角度,然后我们提供旋转角度为30度,最后返回计算好的旋转角度。
我们将rotation3DEffect
修饰符加到视图中。
// 图片视图 func imageCardView() -> some View { ForEach(models) { item in GeometryReader { innerView in Image(item.imageName) .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(10) .padding(.horizontal) .shadow(color: .pink, radius: 5, x: 0, y: 0) .frame(width: innerView.frame(in: .global).width, height: innerView.frame(in: .global).height) .rotation3DEffect(Angle(degrees: getAngle(xOffset: innerView.frame(in: .global).minX)), axis: (x: 0.0, y: 1.0, z: 0.0), anchor: innerView.frame(in: .global).minX > 0 ? .leading : .trailing, perspective: 2.5 ) } } }
我们使用GeometryReader
几何视图来确定图片滚动时的图片的大小,然后使用frame
修饰符调整其滚动时的图片大小变化,最后使用rotation3DEffect
修饰符,设置滚动时的角度变化。
项目预览
恭喜你,完成了整个项目的全部内容!
快来动手试试吧。