网站制作完成,中卫网红大型蹦床设备,网站主机类型,动态图形设计本文我们要在visionOS内实现一个标题输出的动画效果。主要讲ViewModifier协议#xff0c;修饰符#xff08;modifier#xff09;应用于视图或另一个视图修饰符#xff0c;生成原值的另一个版本。在希望创建一个可应用于不同视图的修饰符时可实现ViewModifier…本文我们要在visionOS内实现一个标题输出的动画效果。主要讲ViewModifier协议修饰符modifier应用于视图或另一个视图修饰符生成原值的另一个版本。在希望创建一个可应用于不同视图的修饰符时可实现ViewModifier协议。
首先定义ViewModel本例中的模型比较简单仅定了三个变量分别表示当前文本、标题输出是否完成以及最终的标题文本。
import SwiftUIObservable
class ViewModel {var titleText: String var isTitleFinished: Bool falsevar finalTitle: String 第三回 托内兄如海荐西宾 接外孙贾母惜孤女
}
因模型中有默认值且需要在程序运行的过程中进行修改所以在入口文件中需要将模型注入到环境中
import SwiftUImain
struct visionOSDemoApp: App {State private var model ViewModel()var body: some Scene {WindowGroup() {ContentView().environment(model)}}
}
接下来就是本文的重点了我们需要自定义一个文本修饰符。虽然可以直接将修饰符应用于视图但更常见和地道的做法是使用修饰符来定义一个View来包装这个视图修饰符。我们在代码里就是这么做的在视图中我们传入了5个变量text和isFinished是需要进行修改的所以使用了Bindingcursor定义了光标默认使用了常见的|isAnimated表示是否显示动画。
在TypeTextModifier中可以看到如果isAnimated为false就直接显示最终文本。而在任务中有两个for循环分别设置初始的光标闪烁效果以及后续逐个文字和光标交替输出的效果最后等待片刻标记输出结束。
import SwiftUIextension View {func typeText(text: BindingString,finalText: String,isFinished: BindingBool,curor: String |,isAnimated: Bool true) - some View {self.modifier(TypeTextModifier(text: text,finalText: finalText,isFinished: isFinished,cursor: curor,isAnimated: isAnimated))}
}private struct TypeTextModifier: ViewModifier {Binding var text: Stringvar finalText: StringBinding var isFinished: Boolvar cursor: Stringvar isAnimated: Boolfunc body(content: Content) - some View {content.onAppear {if isAnimated false {text finalTextisFinished true}}.task {guard isAnimated else { return }// Blink the cursor a few timesfor _ in 1...2 {text cursortry? await Task.sleep(for: .milliseconds(500))text try? await Task.sleep(for: .milliseconds(200))}// Type out the titlefor index in finalText.indices {text String(finalText.prefix(through: index)) cursorlet milliseconds (1 UInt64.random(in: 0...1)) * 100try? await Task.sleep(for: .milliseconds(milliseconds))}// Wrap up the title sequencetry? await Task.sleep(for: .milliseconds(400))text finalTextisFinished true}}
}
ContentView内容如下
struct ContentView: View {Environment(ViewModel.self) private var modelvar body: some View {Bindable var model modelNavigationStack {VStack {Spacer()VStack {Text(model.finalTitle).monospaced().font(.system(size: 50, weight: .bold)).padding(.horizontal, 40).hidden().overlay(alignment: .leading) {Text(model.titleText).monospaced().font(.system(size: 50, weight: .bold)).padding(.leading, 40)}Text(林黛玉进贾府).font(.title).padding(.top, 10).opacity(model.isTitleFinished ? 1 : 0)}Spacer()}.typeText(text: $model.titleText, finalText: model.finalTitle, isFinished: $model.isTitleFinished, isAnimated: !model.isTitleFinished)}}
}
这里在屏幕中央输出两段文本第一段会以修饰符的动画效果进行输出直至结束第二段在第一段文本输出完成后显示。 示例代码GitHub仓库
其它相关内容请见虚拟现实(VR)/增强现实(AR)visionOS开发学习笔记