【问题标题】:NSMutableAttributedString strike-through with animationNSMutableAttributedString 带有动画的删除线
【发布时间】:2013-04-01 10:16:26
【问题描述】:
- (void)setStrokeLabel:(BOOL)strokeLabel
{
    _strokeLabel = strokeLabel;

    if (_strokeLabel) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.4 target:self selector:@selector(setStrokeThrough) userInfo:nil repeats:NO];
    } else {
        [self cancelStrokeThrough];
    }
}

- (void)setStrokeThrough
{
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];

    for (NSUInteger i = 1; i <= [attributedString length]; i++) {
        [attributedString addAttribute:NSStrikethroughStyleAttributeName
                                 value:[NSNumber numberWithInt:1]
                                 range:NSMakeRange(0, i)];
        self.attributedText = attributedString;
    }
}

- (void)cancelStrokeThrough
{
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
    [attributedString removeAttribute:NSStrikethroughStyleAttributeName
                                range:NSMakeRange(0, [attributedString length])];
    self.attributedText = attributedString;

}

我想为strike-through 制作动画,比如待办事项动画。 当我为它设置定时器时,定时器只处理如何逐个字母地显示笔触?

【问题讨论】:

  • 这不是动画属性。您能做的最好的事情就是自己设置一个计时器,然后逐字逐句。
  • 谢谢@borrrden,虽然我为它设置了一个NSTimer,但结果并不明显。
  • 不知道你说的“结果不明显”是什么意思
  • 我希望它一个字母一个字母地慢慢敲击,_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(setStrokeThrough) userInfo:nil repeats:NO];有什么错误?
  • 该计时器不会重复,一方面,您应该使用所有相关代码更新您的问题。

标签: ios objective-c


【解决方案1】:

这里有两个功能可以完成这项工作。

    BOOL setStrokethrough(UILabel *label, NSRange range)
    {
        if (range.location >= [label.attributedText length])
            return FALSE;

        if (range.location + range.length > [label.attributedText length])
            range.length = [label.attributedText length] - range.location;

        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];

        [attributedString addAttribute:NSStrikethroughStyleAttributeName
                                 value:@(NSUnderlineStyleSingle)
                                 range:range];

        label.attributedText = attributedString;
        return TRUE;
    }

    -(void)animateSetStrokethroughDuration:(float)duration
    {
        __block float const stepDuration = 0.1;
        float steps = duration / stepDuration;
        __block NSRange range = NSMakeRange(0, ceil((float)[self.label.attributedText length] / steps));

        void (^__block fn)();
        void (^__block __weak weakfn)();

        weakfn = fn = ^(){
            if (!setStrokethrough(self.label, range))
                return;
            range = NSMakeRange(range.location + range.length, range.length);
            [self performBlock:weakfn afterDelay:stepDuration];
        };
        fn();
    }

备注

  1. 为了限制动画时间,我按字符块制作动画,而不是逐个字符。字符串越长,字符块就越长。
  2. __block __weak 业务在here 中解释
  3. self performBlock 是 Mike Ash 对 NSObject 的扩展,并且 还有here
  4. 代码假定您已定义 self.label 成员

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多