0

UITextView で古いテレタイプのようにゆっくりとテキストを表示しようとしています。ビューからスクロールして、行ごとにスムーズに上向きにスクロールするまではうまく機能します。しかし、ただ震え、1回のシフトで上に移動します。以下のスニペット。UI の更新とタイマーに問題があるかどうかわかりませんか?

- (void) refreshLocationDescriptionWith: (NSArray *) inMessageList
{
    //
    // Refresh the location textview by appending new array of string messages
    //

    // Trim old description by half to prevent it growing too long
    //
    int const kMaxTextSize = 2000;
    NSString *oldDescription;
    if ([dispLocationDetails.text length] > kMaxTextSize)
    {
        NSString *trimDescription   = [dispLocationDetails.text substringFromIndex: kMaxTextSize / 2];
        oldDescription              = [NSString stringWithFormat: @"....... %@", trimDescription];
    }
    else
        oldDescription = dispLocationDetails.text;

    // Disable keyboard entry whilst displaying
    [self disableKeyBoardEntry];    

    // Go through all messages and display 'slowly'
    //

    NSTimeInterval nextDelay = 0;
    NSTimeInterval stepDelay = 0.03;

    for (NSString *nextMessage in inMessageList)
    {
        // Add to existing text display with one character at a time, with delay to 'scroll' text
        for (NSRange stringRange = NSMakeRange(0, 1); stringRange.location < [nextMessage length]; stringRange.location += 1)
        {
            NSString *nextChar = [nextMessage substringWithRange: stringRange];            
            [self performSelector: @selector(addCharToLocationDisplay:) withObject: nextChar afterDelay: nextDelay];            
            nextDelay += stepDelay;
        }

        [self performSelector: @selector(addCharToLocationDisplay:) withObject: @"\n" afterDelay: nextDelay];
    }

    [self performSelector: @selector(addCharToLocationDisplay:) withObject: @"\n" afterDelay: nextDelay];

    // Re-enable keyboard entry
    [self performSelector: @selector(enableKeyBoardEntry) withObject: nil afterDelay: nextDelay];

}

- (void) addCharToLocationDisplay: (NSString *) nextChar
{
    //
    // Add one char at a time to the text view display
    //

    NSString *newText                = [NSString stringWithFormat: @"%@%@", dispLocationDetails.text, nextChar];
    self.dispLocationDetails.text    = newText;

    NSRange range = NSMakeRange(dispLocationDetails.text.length - 1, 1);
    [dispLocationDetails scrollRangeToVisible:range];
}
4

1 に答える 1

0

ブロックアニメーションを使って解決しました

// Scroll through text, one char at a time with delay to simulate teletype type display
//
NSTimeInterval nextDelay = 0;
NSTimeInterval stepDelay = 0.03;

if (dispLocationDetails.text.length > 0)
    [self performSelector: @selector(addCharToLocationDisplay:) withObject: @"\n" afterDelay: nextDelay];

for (NSString *nextMessage in inMessageList)
{
    for (NSRange stringRange = NSMakeRange(0, 1); stringRange.location < [nextMessage length]; stringRange.location += 1)
    {
        NSString *nextChar = [nextMessage substringWithRange: stringRange];            
        [self performSelector: @selector(addCharToLocationDisplay:) withObject: nextChar afterDelay: nextDelay];            
        nextDelay += stepDelay;
    }

    [self performSelector: @selector(addCharToLocationDisplay:) withObject: @"\n" afterDelay: nextDelay];
}

- (void) addCharToLocationDisplay: (NSString *) nextChar
{
    //
    // Add one char at a time to the text view display
    // Scroll up line by line as text displayed
    //

    NSString *newText                = [NSString stringWithFormat: @"%@%@", dispLocationDetails.text, nextChar];
    self.dispLocationDetails.text    = newText;

    [UIView animateWithDuration:.25 animations:^
     {
         CGPoint bottomOffset = CGPointMake(0, dispLocationDetails.contentSize.height - dispLocationDetails.bounds.size.height);
         DLog(@"Bottom: %f", bottomOffset.y);
         if (bottomOffset.y > 0)
             [self.dispLocationDetails setContentOffset: bottomOffset animated: NO];
     }];
}
于 2012-10-28T12:06:52.087 に答える