【问题标题】:NSTimer causes UIScrollViews to stop scrolling only on iPod Touch 4th gensNSTimer 导致 UIScrollView 仅在 iPod Touch 4th gens 上停止滚动
【发布时间】:2013-08-02 20:39:58
【问题描述】:

我正在使用以下代码更新 UIView 子类中的自定义 drawRects

NSTimer *timer = [NSTimer timerWithTimeInterval:... 
                                         target:...
                                       selector:....
                                       userInfo:...
                                        repeats:...];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

间隔设置为每 1/30 秒重复运行一次以更新我的 UIView。它似乎工作正常,但我所有的 UIScrollViews 都停止“弹跳”,这意味着,如果我将我的 UIScrollView 滚动到内容框架边界之外,它们不会弹回。这只发生在第 4 代 iPod touch 上。在我的第三代 iPad 和我的 iPhone 5 上,我的 UIScrollViews 反弹回内容框架。 有什么想法吗?

【问题讨论】:

  • 定时器触发方法有什么作用?
  • 同意。而且,根据您的计时器方法正在做什么,您还可以考虑使用CADisplayLink。顺便说一句,旧设备的并发性存在限制(我预计第 3 代会出现问题),但我认为第 4 代(A4 处理器)会很好。但您列出的其他设备是 A5、A5X 或 A6 处理器。你确定 iPod touch 是第 4 代而不是第 3 代吗?
  • @Wain fire 方法在 3 个实例上调用一个方法:setNeedsDisplay。这 3 个实例实现了一个自定义的 drawRect 方法。 drawRect 使用 UIBezierPath 绘制一个笔画圆。
  • @Rob 100% 确定它是第 4 代 iPod touch。

标签: ios uiscrollview nstimer


【解决方案1】:

您的问题必须在别处解决。我测试了一个绘制圆圈的简单自定义视图:

@interface CircleView ()

@property (nonatomic) CFAbsoluteTime startTime;

@end

@implementation CircleView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _startTime = CFAbsoluteTimeGetCurrent();
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    CFAbsoluteTime elapsed = CFAbsoluteTimeGetCurrent() - self.startTime;
    float seconds;
    float fractionsOfSecond = modff(elapsed, &seconds);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextAddArc(context, self.bounds.size.width * fabs(fractionsOfSecond - 0.5) * 2.0, self.bounds.size.height / 2.0, 10.0, 0, M_PI * 2.0, YES);
    CGContextDrawPath(context, kCGPathStroke);
}

@end

我将其中三个添加到滚动视图并启动了一个计时器:

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *circles;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // add three circle views

    CircleView *circle;
    CGRect frame = self.view.bounds;
    CGFloat height = frame.size.height / 3.0;
    frame.size.height = height;

    self.circles = [NSMutableArray arrayWithCapacity:3];
    for (int i = 0; i < 3; i++)
    {
        circle = [[CircleView alloc] initWithFrame:frame];
        circle.backgroundColor = [UIColor clearColor];
        [self.scrollView addSubview:circle];
        self.circles[i] = circle;
        frame.origin.y += height;
    }

    // start timer

    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0/30.0
                                             target:self
                                           selector:@selector(handleTimer)
                                           userInfo:nil
                                            repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)handleTimer
{
    // show the time so I can see the timer in action

    static NSDateFormatter *formatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"HH:mm:ss.SSS";
    });
    self.timeLabel.text = [formatter stringFromDate:[NSDate date]];

    // let's update three circles

    for (UIView *view in self.circles)
        [view setNeedsDisplay];
}

@end

它在第 4 代 iPod Touch 上运行良好。也许您可以分享一些代码,我们可以找出问题的根源。

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 2015-12-26
    相关资源
    最近更新 更多