iOS开发基础144-逐字打印效果
在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-逐字打印效果的更多相关文章
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- iOS开发基础-九宫格坐标(6)
继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...
- iOS开发基础-九宫格坐标(5)
继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...
- iOS开发基础-九宫格坐标(4)
对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...
- iOS开发基础-九宫格坐标(3)之Xib
延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍 Xib 和 storyboard 的比较: 1) X ...
- iOS开发基础-九宫格坐标(2)之模型
在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...
- iOS开发基础-图片切换(4)之懒加载
延续:iOS开发基础-图片切换(3),对(3)里面的代码用懒加载进行改善. 一.懒加载基本内容 懒加载(延迟加载):即在需要的时候才加载,修改属性的 getter 方法. 注意:懒加载时一定要先判断该 ...
- iOS开发基础-图片切换(3)之属性列表
延续:iOS开发基础-图片切换(2),对(2)里面的代码用属性列表plist进行改善. 新建 Property List 命名为 Data 获得一个后缀为 .plist 的文件. 按如图修改刚创建的文 ...
随机推荐
- FRDM-MCXN947开发板之RGB灯
一.背景 RGB LED:通过红.绿.蓝三种颜色组合发光的LED,可以理解由三个不同发光属性的LED组成,这个是LCD平板显示原理的基础,一个LED相当于屏幕上面的一个像素 FRDM-MCXN947集 ...
- 忘记root密码,破解root密码
破解root用户密码: 1.按e进入内核参数重置界面 2.找到开头Linux的段落,行尾输入rd.break 3.按ctrl+x 进入可选步骤 5.以读写方式挂载sysyroot 修改root密码要挂 ...
- Linux驱动--IOCTL实现
参考:[Linux]实现设备驱动的ioctl函数_哔哩哔哩_bilibili.<Linux设备驱动程序(中文第三版).pdf> 1 用户空间ioctl 用户空间的ioctl函数原型,参数是 ...
- JDBC的简单使用以及介绍
JDBC(Java DataBase Connectivity) Java 语言连接数据库 再本模块中,java提供里一组用于连接数据库的类和接口 Java 语言开发者,本身没有提供如何具体连接数据库 ...
- CF1815
CF1815 Div. 1 确实难,Virtual Contest 上只完成了两道题,想出来了三道题. A. Ian and Array Sorting 秒切题--考虑将前 \(n - 1\) 个数变 ...
- reids分片技术cluster篇
为什么学redis-cluster 前面两篇文章,主从复制和哨兵机制保障了高可用 就读写分离,而言虽然slave节点扩展了主从的读并发能力 但是写能力和存储能力是无法进行扩展,就只能是master节点 ...
- 燕千云AITSM重塑IT服务管理
IT服务经历了三个阶段,缘起于设备管理,兴起于灾难恢复,发展于IT服务管理.IT服务发展到目前的阶段,企业所使用的系统功能也由孤立的系统转变为综合的集成系统,IT服务所管理的对象也由核心业务转变为 ...
- 这个vue3的后台管理系统虽然简洁但不简单
今天介绍一个新的Vue后台管理框架,相比其他后台功能丰富管理系统,这个后台管理系统可以用干净简洁来形容--Nova-admin Nova-admin Nova-admin 是一个基于Vue3.Vite ...
- CNN --入门MNIST识别
Smiling & Weeping ---- 下次你撑伞低头看水洼, 就会想起我说雨是神的烟花. 简介:主要是看刘二大人的视频讲解:https://www.bilibili.com/video ...
- package-lock.json 文件
今天有同事找到我说,本地js 编译不过,编译不过的代码如下 const host = window?.location?.host || 'localhost'; 是option chaining, ...