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)"             }         }     } } 

发表评论

评论已关闭。

相关文章