首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

iOS开发基础144-逐字打印效果

编程知识
2024年08月01日 13:32

在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)"
            }
        }
    }
}
From:https://www.cnblogs.com/chglog/p/18336612
本文地址: http://www.shuzixingkong.net/article/666
0评论
提交 加载更多评论
其他文章 利用Curl命令来发邮件的小工具
一个利用curl来发送邮件的小工具 其实可以扩展出很多其它玩法 例如: 配合系统定时任务做系统状态监控,当满足一定条件自动发送邮件 或者和笔者一样,每次加班后懒得编辑邮件,就可以直接传入相应的参数来发邮件 或者...其它可能需要发邮件的场景 字段解释 USER:邮箱帐号名称及密码,中间使用英文冒号:
费曼积分法——以一个简单的例子讲解
今天又又又刷到一个视频,很想睡觉(昨晚熬了个大夜),但是又临近午饭不能睡,只能水篇随笔来打发时间了。 什么是费曼积分法? 先看看官方解释: 费曼积分法(Feynman integral)是一种求解复变函数定积分的计算方法,由理查德&#183;费曼(Richard P. Feynman)提出。这种方法
费曼积分法——以一个简单的例子讲解 费曼积分法——以一个简单的例子讲解 费曼积分法——以一个简单的例子讲解
Python中FastAPI项目使用 Annotated的参数设计
在FastAPI中,你可以使用PEP 593中的Annotated类型来添加元数据到类型提示中。这个功能非常有用,因为它允许你在类型提示中添加更多的上下文信息,例如描述、默认值或其他自定义元数据。 FastAPI支持Annotated类型,这使得你可以为路径操作函数的参数提供额外的元数据,例如依赖
Python中FastAPI项目使用 Annotated的参数设计
稀土领域生产一体化管控系统建设案例
经过2个月的详细调研,**稀土目前缺少生产车间之间数据协同交互、缺少完整的生产工序数据协同监测和分析,无法及时了解生产过程和经营情况,更无法进行有效的生产过程优化。本项目推动**稀土生产环节的数字化、信息化和智能化改造,从行业、战略、技术和市场等方案全面提升**稀土的竞争力,打造**稀土焙烧、水浸、
稀土领域生产一体化管控系统建设案例 稀土领域生产一体化管控系统建设案例 稀土领域生产一体化管控系统建设案例
IDL根据Landsat QA波段去云处理【代码】
IDL根据Landsat QA波段去云处理【代码】 ​ landsat QA波段(质量评估波段)是Landsat卫星影像数据中的一个特殊波段,他在Landsat5-9的每个产品中都存在。虽然我们常用的Landsat影像数据有B1-B7波段,但QA波段并不是其中之一。它可以反映出云、云阴影、雪等类别的
IDL根据Landsat QA波段去云处理【代码】 IDL根据Landsat QA波段去云处理【代码】 IDL根据Landsat QA波段去云处理【代码】
python 音频处理(1)——重采样、音高提取
python音频处理 音高提取 f0 提取pitch基频特征 torchaudio resample 重采样
python 音频处理(1)——重采样、音高提取 python 音频处理(1)——重采样、音高提取 python 音频处理(1)——重采样、音高提取
[rCore学习笔记 020]第二章作业
写在前面 本随笔是非常菜的菜鸡写的。如有问题请及时提出。 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 编程题 实现一个裸机应用程序A,能打印调用栈 首先在这里卡了我很久的是调用栈保存在哪里,回想到上一部分画的
[rCore学习笔记 020]第二章作业 [rCore学习笔记 020]第二章作业 [rCore学习笔记 020]第二章作业
SQL连续查询问题拓展—记上海拼多多非技术岗面试真题
真巧,昨天刚写了关于数据库连续问题的解决方案,没想到今天下午两点就有朋友在上海拼多多面试非技术岗位中就遇到了相似的问题。下面是原题: 一个最大连续支付失败的次数 有一张支付流水表pay;字段如下 id uid time status pay_01 1 2024-01-15 10:00:00 fail