Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios setNeedsDisplay未调用drawRect_Ios_Objective C - Fatal编程技术网

Ios setNeedsDisplay未调用drawRect

Ios setNeedsDisplay未调用drawRect,ios,objective-c,Ios,Objective C,我正在尝试创建一个循环进度指示器。不幸的是,drawRect例程仅在setNeedsDisplay的第一次和最后一次调用,这并没有创建我正在寻找的渐变填充模式。我已经创建了一个UIView子类,在其中填充背景,然后更新绘制进度,如下所示: - (void)drawRect:(CGRect)rect { // draw background CGFloat lineWidth = 5.f; UIBezierPath *processBackgroundPath = [UIB

我正在尝试创建一个循环进度指示器。不幸的是,drawRect例程仅在setNeedsDisplay的第一次和最后一次调用,这并没有创建我正在寻找的渐变填充模式。我已经创建了一个UIView子类,在其中填充背景,然后更新绘制进度,如下所示:

- (void)drawRect:(CGRect)rect
{
    // draw background
    CGFloat lineWidth = 5.f;
    UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
    processBackgroundPath.lineWidth = lineWidth;
    processBackgroundPath.lineCapStyle = kCGLineCapRound;
    CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.width / 2);
    CGFloat radius = (self.bounds.size.width - lineWidth) / 2;
    CGFloat startAngle = (2 * (float)M_PI / 2); // 90 degrees
    CGFloat endAngle = (2 * (float)M_PI) + startAngle;
    [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [[UIColor grayColor] set];
    [processBackgroundPath stroke];

    // draw progress
    UIBezierPath *processPath = [UIBezierPath bezierPath];
    processPath.lineCapStyle = kCGLineCapRound;
    processPath.lineWidth = lineWidth;
    endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
    [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [[UIColor blackColor] set];
    [processPath stroke];
}
我使用以下方法设置进度变量:

- (void)setProgress:(float)progress {
    _progress = progress;
    [self setNeedsDisplay];
}
然后,在将具有上述类的UIView分配给我的故事板后,我只需在我的主viewcontroller中调用附加的方法:

- (void)progressView:(CircularProgress *)activityView loopTime:(CGFloat)duration repeats:(BOOL)repeat {
    float portion = 0.0f;
    while (portion < 1.0f) {
        portion += 1/ (20.0 * duration);
        [activityView setProgress:portion];
        usleep(50000);
    }
}
-(void)progressView:(CircularProgress*)活动视图loopTime:(CGFloat)持续时间重复:(BOOL)重复{
浮动部分=0.0f;
而(部分<1.0f){
部分+=1/(20.0*持续时间);
[活动视图设置进度:部分];
美国LEEP(50000);
}
}
同样,[self-setNeedsDisplay]只在第一次和最后一次调用drawRect。提前感谢您的帮助。

usleep(50000)
阻止线程

使用
NSTimer
更新progressView

[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(updateProgressView) userInfo:nil repeats:YES];
duration = 0;
...


- (void)updateProgressView {
    // Update the progress
  }
}
...
usleep(50000)
阻塞线程

使用
NSTimer
更新progressView

[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(updateProgressView) userInfo:nil repeats:YES];
duration = 0;
...


- (void)updateProgressView {
    // Update the progress
  }
}
...

将在主线程上调用
drawRect:
progressView:…
方法


setNeedsDisplay:
不会立即调用
drawRect:
;它将其排队,以便下次应用程序的主线程通过其运行循环时调用。使用
NSTimer
或阅读CoreAnimation,看看它是否提供了更直接适用的内容:您当前的解决方案将占用大量CPU时间,并且不会利用GPU。

您的
drawRect:
progressView:…
方法都将在主线程上调用


setNeedsDisplay:
不会立即调用
drawRect:
;它将其排队,以便下次应用程序的主线程通过其运行循环时调用。使用
NSTimer
或阅读CoreAnimation,看看它是否提供了更直接适用的功能:您当前的解决方案将占用大量CPU时间,并且不会利用GPU。

作为
NSTimer
的替代方案,我还建议使用:

CADisplayLink对象是允许应用程序运行的计时器对象 将其图形与显示的刷新率同步

应用程序创建一个新的显示链接,提供一个目标对象 以及在屏幕更新时调用的选择器。接下来,你的 应用程序将显示链接添加到运行循环

显示链接与运行循环关联后,选择器将打开 当需要更新屏幕内容时,调用目标


这将确保重新绘制进度视图时与设备帧速率大致同步。

作为
NSTimer
的替代方法,我还建议使用:

CADisplayLink对象是允许应用程序运行的计时器对象 将其图形与显示的刷新率同步

应用程序创建一个新的显示链接,提供一个目标对象 以及在屏幕更新时调用的选择器。接下来,你的 应用程序将显示链接添加到运行循环

显示链接与运行循环关联后,选择器将打开 当需要更新屏幕内容时,调用目标


这将确保重新绘制进度视图时与设备帧速率大致同步。

谢谢您的回复。我用计时器和方法替换了原来的方法,该方法增加计数器并在自定义视图上调用setProgress方法。不幸的是,我仍然有同样的问题。欢迎您的建议。谢谢您的回复。我用计时器和方法替换了原来的方法,该方法增加计数器并在自定义视图上调用setProgress方法。不幸的是,我仍然有同样的问题。接受建议。这是唯一有效的解决方案。非常感谢。这里有一个很好的例子。非常感谢!!!这是唯一有效的解决方案。非常感谢。这里有一个很好的例子。非常感谢!!!