处理流逝返回
处理粘贴
This commit is contained in:
@@ -9,6 +9,13 @@
|
||||
@interface KBStreamOverlayView ()
|
||||
@property (nonatomic, strong) KBStreamTextView *textViewInternal;
|
||||
@property (nonatomic, strong) UIButton *closeButton;
|
||||
|
||||
// 新增:流式打字机用的缓冲 & 定时器
|
||||
@property (nonatomic, strong) NSMutableString *pendingText;
|
||||
@property (nonatomic, strong) NSTimer *streamTimer;
|
||||
@property (nonatomic, assign) NSInteger charsPerTick; // 每次“跳”几个字符
|
||||
// 新增:标记 SSE 已经收到 done
|
||||
@property (nonatomic, assign) BOOL streamDidReceiveDone;
|
||||
@end
|
||||
|
||||
@implementation KBStreamOverlayView
|
||||
@@ -34,6 +41,10 @@
|
||||
make.height.mas_equalTo(28);
|
||||
make.width.mas_greaterThanOrEqualTo(56);
|
||||
}];
|
||||
_pendingText = [NSMutableString string];
|
||||
_charsPerTick = 2; // 每次输出 1~2 个字符,可以自己调
|
||||
_streamDidReceiveDone = NO;
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -67,13 +78,73 @@
|
||||
|
||||
- (void)appendChunk:(NSString *)text {
|
||||
if (text.length == 0) return;
|
||||
[self.textViewInternal appendStreamText:text];
|
||||
if (![NSThread isMainThread]) {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf appendChunk:text];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
[self.pendingText appendString:text];
|
||||
[self startStreamTimerIfNeeded];
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
[self.textViewInternal finishStreaming];
|
||||
- (void)startStreamTimerIfNeeded {
|
||||
if (self.streamTimer) return;
|
||||
self.streamTimer = [NSTimer scheduledTimerWithTimeInterval:0.02
|
||||
target:self
|
||||
selector:@selector(handleStreamTick)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
}
|
||||
|
||||
- (void)stopStreamTimer {
|
||||
[self.streamTimer invalidate];
|
||||
self.streamTimer = nil;
|
||||
}
|
||||
|
||||
- (void)handleStreamTick {
|
||||
if (self.pendingText.length == 0) {
|
||||
// 如果已经收到 done 并且没有待播内容了,这里再真正 finish
|
||||
if (self.streamDidReceiveDone) {
|
||||
[self.textViewInternal finishStreaming];
|
||||
}
|
||||
[self stopStreamTimer];
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger len = MIN(self.charsPerTick, self.pendingText.length);
|
||||
NSString *slice = [self.pendingText substringToIndex:len];
|
||||
[self.pendingText deleteCharactersInRange:NSMakeRange(0, len)];
|
||||
|
||||
[self.textViewInternal appendStreamText:slice];
|
||||
}
|
||||
|
||||
|
||||
- (void)finish {
|
||||
if (![NSThread isMainThread]) {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf finish];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 只标记“流已结束”
|
||||
self.streamDidReceiveDone = YES;
|
||||
|
||||
// 如果此时已经没有待播内容了,可以立即结束
|
||||
if (self.pendingText.length == 0) {
|
||||
[self stopStreamTimer];
|
||||
[self.textViewInternal finishStreaming];
|
||||
}
|
||||
// 否则等 handleStreamTick 把 pendingText 慢慢播完,
|
||||
// 它看到 pendingText == 0 且 streamDidReceiveDone == YES 时会自动调用 finishStreaming
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (KBStreamTextView *)textView { return self.textViewInternal; }
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user