同期されたショーの歌詞アプリを作成し、すべての歌詞をUITextView
. NSAttributedString
現在の歌詞を強調するために、背景色をofに追加しますUITextView
。NSRange
に格納されているすべての行NSArray
。
私のコードは非常に単純です。ボタンをタップするとハイライト行が下に移動します(UITextViewのset contentOffsetを介して)。しかし、ここで奇妙な問題が発生しました。最初はUITextView
ちゃんとスクロールしていたcontentOffset
のですが、UITextView
それ以上にframe.size.height
なると修正されました。
これが私のコードです:
//View controller
#import "ViewController.h"
@interface ViewController () {
NSUInteger globelIndex;
NSArray *textRanges;
NSMutableAttributedString *attributedText;
}
@property (weak, nonatomic) IBOutlet UITextView *lyricView;
@property (strong, nonatomic) NSTimer *mainTimer;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *rawText = [self readFile];
globelIndex = 0;
[self initTextLines:rawText];
attributedText = [[NSMutableAttributedString alloc] initWithString:rawText
attributes:@{NSBackgroundColorAttributeName: [UIColor orangeColor]}];
self.lyricView.attributedText = [attributedText copy];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)manualNextLine:(UIButton *)sender {
[self updateTextView];
}
- (IBAction)autoNextLineUsingNSTimer:(UIButton *)sender {
self.mainTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTextView) userInfo:nil repeats:YES];
}
- (void)updateTextView {
if (self.lyricView.contentOffset.y >= self.lyricView.contentSize.height &&
self.mainTimer)
{
self.mainTimer = nil;
return;
}
NSMutableAttributedString *mat = [attributedText mutableCopy];
NSValue *value = [textRanges objectAtIndex:globelIndex];
[mat addAttribute:NSBackgroundColorAttributeName value:[UIColor whiteColor] range:[value rangeValue]];
self.lyricView.attributedText = [mat copy];
globelIndex += 1;
// self.textView.contentOffset = CGPointMake(self.textView.contentOffset.x, self.textView.contentOffset.y + 24);
// [self.textView scrollRangeToVisible:[value rangeValue]];
CGPoint newOffset = CGPointMake(self.lyricView.contentOffset.x, self.lyricView.contentOffset.y + 20);
[self.lyricView setContentOffset:newOffset animated:NO];
NSLog(@"[%@ %@] h: %f b: %f a: %f", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.lyricView.contentSize.height, newOffset.y, self.lyricView.contentOffset.y);
}
#pragma mark - helper
- (void)initTextLines:(NSString *)rawText {
NSMutableArray *result = [@[] mutableCopy];
NSArray *t = [rawText componentsSeparatedByString:@"\r\n"];
__block int index = 0;
[t enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *s = obj;
NSRange range = NSMakeRange(index, s.length + 2);
[result addObject:[NSValue valueWithRange:range]];
index += s.length + 2;
}];
textRanges = [result copy];
}
- (NSString *)readFile {
NSError *error = nil;
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"二人の季節が-ささきのぞみ-想い" withExtension:@"lrc"];
NSString *content = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:&error];
if (error) {
if (DEBUG) NSLog(@"[%@ %@] Error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
abort();
}
return content;
}
@end
私のコードはすべてViewControllerにあり、StoryBoard
2つのUIButtonとUITextViewがあります。私が疑問に思っているのは、「UITextView.contentOffset があるサイズを超えると変更できない理由」です。