在AIGC类的APP中,实现那种一个字一个字、一行一行地打印出文字的效果,可以通过多种方法来实现。下面是一些实现方法,使用Swift和OC来举例说明。

OC版

1. 基于定时器的逐字打印效果

可以使用NSTimer来逐字逐行地显示文字。

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UITextView *textView;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, strong) NSTimer *timer; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; self.textView = [[UITextView alloc] initWithFrame:self.view.bounds];
self.textView.font = [UIFont systemFontOfSize:18];
self.textView.editable = NO;
self.textView.scrollEnabled = YES;
[self.view addSubview:self.textView]; self.content = @"这是需要逐字逐行打印的文字内容。\n让我们来实现它。";
self.currentIndex = 0; [self startPrinting];
} - (void)startPrinting {
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(printNextCharacter) userInfo:nil repeats:YES];
} - (void)printNextCharacter {
if (self.currentIndex >= self.content.length) {
[self.timer invalidate];
self.timer = nil;
return;
} NSRange range = NSMakeRange(self.currentIndex, 1);
NSString *nextCharacter = [self.content substringWithRange:range];
self.textView.text = [self.textView.text stringByAppendingString:nextCharacter]; self.currentIndex += 1;
} @end

2. 使用CADisplayLink来实现高精度逐字打印

CADisplayLink可以在屏幕刷新时调用指定的方法,相较于NSTimer,其精度和性能更高。

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UITextView *textView;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, strong) CADisplayLink *displayLink; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; self.textView = [[UITextView alloc] initWithFrame:self.view.bounds];
self.textView.font = [UIFont systemFontOfSize:18];
self.textView.editable = NO;
self.textView.scrollEnabled = YES;
[self.view addSubview:self.textView]; self.content = @"这是需要逐字逐行打印的文字内容。\n让我们来实现它。";
self.currentIndex = 0; [self startPrinting];
} - (void)startPrinting {
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(printNextCharacter)];
self.displayLink.preferredFramesPerSecond = 10; // 控制打印速度
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
} - (void)printNextCharacter {
if (self.currentIndex >= self.content.length) {
[self.displayLink invalidate];
self.displayLink = nil;
return;
} NSRange range = NSMakeRange(self.currentIndex, 1);
NSString *nextCharacter = [self.content substringWithRange:range];
self.textView.text = [self.textView.text stringByAppendingString:nextCharacter]; self.currentIndex += 1;
} @end

3. CATextLayer + Animation

还可以使用CATextLayer和动画来实现更为复杂和流畅的逐字逐行打印效果。

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h> @interface ViewController () @property (nonatomic, strong) CATextLayer *textLayer;
@property (nonatomic, strong) NSString *content; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; self.textLayer = [CATextLayer layer];
self.textLayer.frame = self.view.bounds;
self.textLayer.fontSize = 18;
self.textLayer.alignmentMode = kCAAlignmentLeft;
self.textLayer.contentsScale = [UIScreen mainScreen].scale;
self.textLayer.wrapped = YES;
[self.view.layer addSublayer:self.textLayer]; self.content = @"这是需要逐字逐行打印的文字内容。\n让我们来实现它。"; [self startPrinting];
} - (void)startPrinting {
self.textLayer.string = @""; for (NSInteger index = 0; index < self.content.length; index++) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(index * 0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSString *nextCharacter = [self.content substringWithRange:NSMakeRange(index, 1)];
self.textLayer.string = [self.textLayer.string stringByAppendingString:nextCharacter];
});
}
} @end

Swift版

1. 基于定时器的逐字打印效果

可以使用Timer来逐字逐行地显示文字。

import UIKit

class ViewController: UIViewController {
private let textView = UITextView()
private let content = "这是需要逐字逐行打印的文字内容。\n让我们来实现它。"
private var currentIndex = 0
private var timer: Timer? override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textView)
textView.frame = view.bounds
textView.font = UIFont.systemFont(ofSize: 18)
textView.isEditable = false
textView.isScrollEnabled = true
startPrinting()
} private func startPrinting() {
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(printNextCharacter), userInfo: nil, repeats: true)
} @objc private func printNextCharacter() {
guard currentIndex < content.count else {
timer?.invalidate()
timer = nil
return
} let nextIndex = content.index(content.startIndex, offsetBy: currentIndex)
textView.text.append(content[nextIndex])
currentIndex += 1
}
}

2. 使用CADisplayLink来实现高精度逐字打印

CADisplayLink可以在屏幕刷新时调用指定的方法,相较于Timer,其精度和性能更高。

import UIKit

class ViewController: UIViewController {
private let textView = UITextView()
private let content = "这是需要逐字逐行打印的文字内容。\n让我们来实现它。"
private var currentIndex = 0
private var displayLink: CADisplayLink? override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textView)
textView.frame = view.bounds
textView.font = UIFont.systemFont(ofSize: 18)
textView.isEditable = false
textView.isScrollEnabled = true
startPrinting()
} private func startPrinting() {
displayLink = CADisplayLink(target: self, selector: #selector(printNextCharacter))
displayLink?.preferredFramesPerSecond = 10 // 控制打印速度
displayLink?.add(to: .main, forMode: .default)
} @objc private func printNextCharacter() {
guard currentIndex < content.count else {
displayLink?.invalidate()
displayLink = nil
return
} let nextIndex = content.index(content.startIndex, offsetBy: currentIndex)
textView.text.append(content[nextIndex])
currentIndex += 1
}
}

3. CATextLayer + Animation

还可以使用CATextLayer和动画来实现更为复杂和流畅的逐字逐行打印效果。

import UIKit

class ViewController: UIViewController {
private let textLayer = CATextLayer()
private let content = "这是需要逐字逐行打印的文字内容。\n让我们来实现它。" override func viewDidLoad() {
super.viewDidLoad() textLayer.frame = view.bounds
textLayer.fontSize = 18
textLayer.alignmentMode = .left
textLayer.contentsScale = UIScreen.main.scale
textLayer.isWrapped = true
view.layer.addSublayer(textLayer) startPrinting()
} private func startPrinting() {
textLayer.string = ""
for (index, character) in content.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.1) {
self.textLayer.string = "\(self.textLayer.string ?? "")\(character)"
}
}
}
}

iOS开发基础144-逐字打印效果的更多相关文章

  1. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

  2. iOS开发——总结篇&IOS开发基础知识

    IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...

  3. IOS开发基础环境搭建

    一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包:       ...

  4. iOS开发基础-九宫格坐标(6)

    继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...

  5. iOS开发基础-九宫格坐标(5)

    继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...

  6. iOS开发基础-九宫格坐标(4)

    对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...

  7. iOS开发基础-九宫格坐标(3)之Xib

    延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍  Xib 和 storyboard 的比较: 1) X ...

  8. iOS开发基础-九宫格坐标(2)之模型

    在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...

  9. iOS开发基础-图片切换(4)之懒加载

    延续:iOS开发基础-图片切换(3),对(3)里面的代码用懒加载进行改善. 一.懒加载基本内容 懒加载(延迟加载):即在需要的时候才加载,修改属性的 getter 方法. 注意:懒加载时一定要先判断该 ...

  10. iOS开发基础-图片切换(3)之属性列表

    延续:iOS开发基础-图片切换(2),对(2)里面的代码用属性列表plist进行改善. 新建 Property List 命名为 Data 获得一个后缀为 .plist 的文件. 按如图修改刚创建的文 ...

随机推荐

  1. 【VMware vSphere】使用vSphere Lifecycle Manager(vLCM)管理独立主机和集群的生命周期。

    vSphere Lifecycle Manager(vLCM)是 vSphere 7 中引入的一项新功能,它提供了一种集中式.自动化和简单性的方式来管理和升级 vSphere 基础架构组件(如vCen ...

  2. c语言不可不说的一件事——进制之间的转化

    进制之间的转换 二进制转换 二进制转换为十进制 10111010.101 转换方法: 个位数是乘以2的0次方 从小数点开始分割,(小数点前从右往左,小数点后从左往右)乘以2的对应次方(从0开始取),最 ...

  3. node写接受

    选择数据库类型:mongodb 定义用户集合的字段(域): 用户名  密码  性别  爱好(多选)  简介 npm i -S express mongoose 在项目中连接mongodb服务 inde ...

  4. webpack externals忽略不打入的包

    例如项目中使用从 CDN 引入 jQuery,而不是把它打包进来使用 import $ from 'jquery' webpack.config.js externals: { jquery: 'jQ ...

  5. Vue学习:18.Vue插槽

    Vue 中的插槽(slot)是一种灵活的机制,用于在父组件中将内容传递到子组件的特定位置.它允许我们在子组件中定义可以在父组件中传递任意内容的"插槽",从而实现更灵活的组件化. 在 ...

  6. Vue学习:3.V标签综合3

    接上一篇... V标签综合使用:记事本案例 功能: 在实现列表渲染和删除功能的基础上,增加了数据添加以及数据统计,同时要求底部统计和清空区域在事件数目为0时不显示. 思路: 整体架构分为三部分:头部使 ...

  7. opc da 服务器数据 转 profinet IO项目案例

    1         案例说明 1.   在OPC DA服务器上运行OPC DA client软件查看OPC DA服务器的相关参数. 2.   配置VFBOX网关参数,使用网关采集OPC DA服务器数据 ...

  8. P8594 「KDOI-02」一个仇的复

    我会组合数! 首先发现同一列只有被不同的横块填或被一个相同的竖块填,且用竖块填完1列之后,会分成两个封闭的长方形,而长方形内部则用横块来填充. 先考虑一个子问题,某个 \(2 \times n\) 长 ...

  9. 对Transformer的一些理解

    在学习Transformer这个模型前对seq2seq架构有个了解时很有必要的 先上图 输入和输出 首先理解模型时第一眼应该理解输入和输出最开始我就非常纠结 有一个Inputs,一个Outputs(s ...

  10. windows10 iis 环境下部署 asp.net core 应用程序的步骤

    1.运行powershell,在运行窗口中输入:powershell,点回车,如下图: 2.安装choco,在打开的powershell窗口中输入:Set-ExecutionPolicy Bypass ...