CATextLayer仅在一段时间后显示其内容

马特奥普克

我知道这听起来很奇怪,但问题恰恰在于:我有一个ViewController加载了一个与Grand Central Dispatch异步的CSV文件(该文件表示一个直方图)。我还有一个名为的自定义视图HistogramView控制器完成CSV文件的加载后,将invalidate在上调用一个函数HistogramView在该函数中,视图解析从文件读取的数据并创建:

  1. 代表直方图条形的一些CAShapeLayer
  2. 一些CATextLayer代表条形标签

对于形状层没有问题,所有方法都很好。文本层出现问题:最初仅显示背景。文本仅在几秒钟后出现:-/,这很奇怪。这是invalidate函数的代码(正如我所说的,该函数在自定义视图中)。

-(void)invalidate{
    float tempX = 0;
    float tempHeight = 0;
    NSArray *data;

    if([self.dataSource getHistogramData] != nil){
        data = [self.dataSource getHistogramData];
        tempX = [self getStartingX];
        [self getDataMaxValue];

        for (int i=0; i<[data count]; i+=2) {

            //THE SHAPE LAYER THAT REPRESENTS AN HISTOGRAM BAR
            tempHeight = [self uniformValue:[[data objectAtIndex:i+1] intValue]];
            CAShapeLayer *rectLayer = [CAShapeLayer layer];
            CGRect rect = CGRectMake(tempX, tempHeight, barWidth, height - tempHeight - spaceForLabels);
            rectLayer.path = CGPathCreateWithRect(rect, nil);
            [rectLayer setBackgroundColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor];
            [self.layer addSublayer:rectLayer];


            //THE TEXT LAYER THAT REPRESENTS A LABEL FOR THE BAR
            CATextLayer *textLayer = [CATextLayer layer];
            textLayer.frame = CGRectMake(tempX, height - spaceForLabels, barWidth, spaceForLabels);
            textLayer.font = CFBridgingRetain([UIFont boldSystemFontOfSize:18].fontName);
            textLayer.fontSize = 18;
            textLayer.foregroundColor = [UIColor redColor].CGColor;
            textLayer.backgroundColor = [UIColor yellowColor].CGColor;
            textLayer.alignmentMode = kCAAlignmentCenter;
            textLayer.string = @"example";
            [self.layer addSublayer:textLayer];


            tempX += barWidth + spaceBetweenBars;
        }

    }
}

如您所见,我以相同的方式在同一点创建条形图和标签。先感谢您。

编辑:在我的视图控制器中,我以viewDidLoad这种方式进行方法内的工作

- (void)viewDidLoad {
    [super viewDidLoad];

    //create the channel with which read the CSV file
    dispatch_io_t ch = dispatch_io_create_with_path(DISPATCH_IO_STREAM, [[[NSBundle mainBundle] pathForResource:@"histogram1" ofType:@"csv"] UTF8String], O_RDONLY, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), nil);

    //read the CSV file async with GCD
    [self readCSVFile:ch];

    //set the delegates for the histogram view
    self.histogramView.delegate = self;
    self.histogramView.dataSource = self;
}

-(void)readCSVFile:(dispatch_io_t)ch{

    //the string that represents the content of CSV file
    NSMutableString __block *stringFromData;

    //read the whole file
    dispatch_io_read(ch, 0, SIZE_MAX, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(bool done, dispatch_data_t dataRead, int error) {

        if(!error && !done){

            //convert from dispatch_data_t to NSString
            size_t dataSize = dispatch_data_get_size(dataRead);
            stringFromData = [[NSMutableString alloc]initWithCapacity:dataSize];
            dispatch_data_apply(dataRead, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
                [stringFromData appendFormat:@"%.*s", (unsigned int)size, buffer];
                return true;
            });
        }else{
            dispatch_io_close(ch, 0);
            data = [stringFromData componentsSeparatedByCharactersInSet:
                       [NSCharacterSet characterSetWithCharactersInString:@"\n,"]];

            //AND NOW I CALL INVALIDATE ON THE VIEW
            [self.histogramView invalidate];
        }

    });
}
马特奥普克

好的我明白了。我要感谢rdelmar,他的建议为我指出了问题所在。如他所说,invalidate不是从主线程调用,而是从后台线程(读取文件的线程)调用。这是错误的,因为必须从主线程更新视图。因此,我仅通过invalidate这种方式调用方法来解决问题

-(void)readCSVFile:(dispatch_io_t)ch{

    //the string that represents the content of CSV file
    NSMutableString __block *stringFromData;

    //read the whole file
    dispatch_io_read(ch, 0, SIZE_MAX, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(bool done, dispatch_data_t dataRead, int error) {

        if(!error && !done){

            //convert from dispatch_data_t to NSString
            size_t dataSize = dispatch_data_get_size(dataRead);
            stringFromData = [[NSMutableString alloc]initWithCapacity:dataSize];
            dispatch_data_apply(dataRead, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
                [stringFromData appendFormat:@"%.*s", (unsigned int)size, buffer];
                return true;
            });
        }else{
            dispatch_io_close(ch, 0);
            data = [stringFromData componentsSeparatedByCharactersInSet:
                       [NSCharacterSet characterSetWithCharactersInString:@"\n,"]];

            //HERE IS THE SOLUTION
            [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                [self.histogramView invalidate];
            }];
        }

    });
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

AngularJS:仅在一段时间后才显示对ajax请求加载微调器

来自分类Dev

在一段时间后显示所选列表项的内容

来自分类Dev

直到一段时间后才显示div

来自分类Dev

一段时间后,下拉选项以浅色显示

来自分类Dev

一段时间后,下拉选项以浅色显示

来自分类Dev

一段时间后翻转

来自分类Dev

Internet上的WOL成功了一段时间,但一段时间后失败了

来自分类Dev

如何创建仅在输入停止一段时间后才输出的信号或流?

来自分类Dev

一段时间不活动后显示一个对话框

来自分类Dev

在显示实际网页之前显示一段时间

来自分类Dev

一段时间后此弹出窗口如何显示和消失

来自分类Dev

一段时间后隐藏用angularjs表单验证显示的错误标签

来自分类Dev

延迟一段时间后如何显示新视图

来自分类Dev

等待一段时间后显示装载机的精妙方法是什么?

来自分类Dev

从表中选择值并在一段时间后显示?

来自分类Dev

一段时间后如何自动关闭第二台显示器?

来自分类Dev

AMP HTML 超时事件在一段时间后打开/显示灯箱

来自分类Dev

在一段时间之前grep特定内容

来自分类Dev

在一段时间之前grep特定内容

来自分类Dev

OpenGL:将屏幕内容暂停一段时间

来自分类Dev

一段时间后运行TextView选框

来自分类Dev

在Android中一段时间后隐藏TextView

来自分类Dev

闲置一段时间后,MariaDB无法工作

来自分类Dev

一段时间后blpop停止处理队列

来自分类Dev

NLog在一段时间后停止运行

来自分类Dev

Chrome:onaudioprocess在一段时间后停止被调用

来自分类Dev

一段时间后SignalR停止工作

来自分类Dev

在一段时间后更改div的类

来自分类Dev

Java Runtime exec()在一段时间后被卡住

Related 相关文章

热门标签

归档