处理流逝返回

处理粘贴
This commit is contained in:
2025-12-09 16:12:54 +08:00
parent 7b86b739eb
commit e39104c431
4 changed files with 106 additions and 17 deletions

View File

@@ -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