SwiftUI模块系列 - 已更新18篇
SwiftUI项目 - 已更新1个项目
往期Demo源码下载
技术:SwiftUI、SwiftUI3.0、支付宝、余额宝、数字动画
运行环境:
SwiftUI3.0 + Xcode13.4.1 + MacOS12.5 + iPhone Simulator iPhone 13 Pro Max
SwiftUI搭建一个类似支付宝中的余额宝余额数字动画效果
概述详细一、运行效果二、项目结构图三、程序实现 - 过程1.创建一个项目命名为 `RollingCounter`1.1.引入资源文件和颜色2. 创建一个虚拟文件`New Group` 命名为 `View`2. 创建一个文件`New File` 选择`SwiftUI View`类型 命名为`RollingText`CodeContentView - 主窗口Home - 主页概述
SwiftUI搭建一个类似支付宝中的
余额宝
余额数字动画效果
详细
一、运行效果
二、项目结构图
三、程序实现 - 过程
思路
先看一下原理图
2. 其实就是在视图里面创建一排数字比如 0~9 垂直排列展示 然后将其他部分进行切割
3. 拿到当前的数字 和 之前的数字进行每一个位数进行比较
如果是当前数字位数大于之前位数 就向上滚动。
如果当前位数小数之前的尾数就向下滚动
1.创建一个项目命名为RollingCounter
1.1.引入资源文件和颜色
无
2. 创建一个虚拟文件New Group
命名为View
2. 创建一个文件New File
选择SwiftUI View
类型 命名为RollingText
主要是:处理数字的动画效果
Code
ContentView - 主窗口
主要是展示主窗口
Home
和手动改变随机数
//// ContentView.swift// Shared//// Created by lyh on /8/29.//import SwiftUIstruct ContentView: View {@State var value :Int = 0var body: some View {NavigationView{VStack(spacing:25){RollingText(font: .system(size: 55), weight: .black, value: $value)Button("change Value"){value = .random(in: 100...2999)}}.padding().navigationTitle("RollingCounter")}}}struct ContentView_Previews: PreviewProvider {static var previews: some View {ContentView()}}
Home - 主页
思路
先看一下原理图
2. 其实就是在视图里面创建一排数字比如 0~9 垂直排列展示 然后将其他部分进行切割
3. 拿到当前的数字 和 之前的数字进行每一个位数进行比较
如果是当前数字位数大于之前位数 就向上滚动。
如果当前位数小数之前的尾数就向下滚动
//// RollingText.swift// RollingCounter (iOS)//// Created by lyh on /8/30.//import SwiftUIstruct RollingText: View {// 文本属性var font : Font = .largeTitlevar weight : Font.Weight = .regular@Binding var value : Int// 动画属性@State var animationRange: [Int] = []var body: some View {HStack(spacing:0){ForEach(0..<animationRange.count,id: \.self){index in//查找给定字体的文本大小Text("8").font(font).fontWeight(weight).opacity(0).overlay{GeometryReader{proxy inlet size = proxy.sizeVStack(spacing:0){// MARK:因为它的个人价值//我们需要从0到9ForEach(0...9,id: \.self){number inText("\(number)").font(font).fontWeight(weight).frame(width:size.width,height:size.height,alignment: .top)}}// 设置偏移量.offset(y:-CGFloat(animationRange[index]) * size.height)}.clipped()}}}.onAppear{// 加载范围animationRange = Array(repeating: 0, count: "\(value)".count)DispatchQueue.main.asyncAfter(deadline: .now() + 0.06) {updateText()}}.onChange(of: value) {newValue in// 处理额外价值的添加/移除let extra = "\(value)".count - animationRange.countif extra > 0{// 添加额外的范围for _ in 0..<extra {withAnimation(.easeIn(duration:0.1)){animationRange.append(0)}}}else{for _ in 0..<(-extra) {withAnimation(.easeIn(duration:0.1)){animationRange.removeLast()}}}updateText()}}func updateText(){let stringValue = "\(value)"for(index,value) in zip(0..<stringValue.count, stringValue){//如果First Value = 1//然后Offset将被应用为-1//所以文本将向上移动显示1Value// 基于指标值的阻尼分数var fraction = Double(index) * 0.15// Max = 0.5// Total = 1.5fraction = (fraction > 0.5 ? 0.5 : fraction)withAnimation(.interactiveSpring(response: 0.8, dampingFraction: 1, blendDuration: 1 + fraction)){animationRange[index] = (String(value) as NSString).integerValue}}}}struct RollingText_Previews: PreviewProvider {static var previews: some View {ContentView()}}