Autolayout和iOS7,以编程方式添加UIImageView不会出现 - 似乎线程相关

时间:2014-01-07 14:06:13

标签: cocoa-touch ios7 uiimageview constraints autolayout

我有一个充满UIImages的阵列。我将每个图像加载到UIImageView中,然后将UIImageView添加到UIView,一旦UIView被添加到显示器上的UIView。

当我将带有UIImageViews的UIView添加到屏幕上没有出现的其他UIView时(iOS6中都很好),问题出现在iOS7中。如果我然后按主页按钮,然后返回应用程序,图像就在那里!

我知道这听起来有点奇怪,因为我可以将UIView从过程中删除但是有一个原因。还有一个原因是我不将UIImages作为UIImageViews存储在数组中。

UIView *layerViewToAdd = [[UIView alloc]initWithFrame:presentationDisplay.frame];

for(UIImage tempImage in currentImages)
{
        UIImageView *tempImageView = [[UIImageView alloc]initWithFrame:presentationDisplay.frame];
        [tempImageView setImage:tempImage];
        [layerViewToAdd addSubview:tempImageView];
}

[presentationDisplay addSubview:layerViewToAdd];

我试图强制使用[presentation setNeedsDisplay]和[presentationDisplay setNeedsLayout]重绘屏幕但不起作用。我认为问题与Autolayout / Constraints有关,但不确定。

修改

好吧我已经隔离了代码,它似乎与线程相关。看下面的代码我在背景中调用redrawLayersInBackground,这是上面的FOR循环,然后我在主线程上调用presentLayersInView,它添加了已经显示的View(上面的最后一行或多或少) - 对不起我知道我已经删除了很多代码,但它不仅仅是这个(经验教训)。这在iOS6中运行良好,但在iOS7中运行不正常,如果我取出所有调度位,它在两者中都能正常工作。

有没有更好的方法在后台构建内容然后添加到前台?

backgoundQueue = dispatch_queue_create("createlayers", 0);

dispatch_async(backgoundQueue, ^{

    UIView *layerViewToAdd = [self redrawLayersInBackground];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self presentLayersInView:layerViewToAdd];

    });

});

另一个编辑

这是整个代码;

它将视图的各层存储在一个数组中,并进行一些比较和测试,以确定在再次下载之前我们是否已经拥有该层。下来的图像很大,这就是我经历这么多麻烦的原因!

-(UIView *)redrawLayersInBackground
{
    int layerCount = 0;


    // This is the view which will contain all the new layers
    UIView *layerViewToAdd = [[UIView alloc]initWithFrame:presentationDisplay.frame];

    // Take a copy of all the layers then clear then, the copy will be used as a cache to build a new set of layers
    NSArray *tempLayerNames = [[NSArray alloc]initWithArray:layerNames];
    NSArray *tempLayerImages = [[NSArray alloc]initWithArray:layerImages];

    [layerNames removeAllObjects];
    [layerImages removeAllObjects];


    // This for is just to loop through all items, the dictionary is not used
    for (NSDictionary *enforceLoop in currentSetupInfo[@"layers"])
    {

        NSString *layerName =currentSetupInfo[@"layers"][[NSString stringWithFormat:@"layer%i", layerCount]];

        BOOL isFound = NO;
        UIImage *tempImage;
        UIImageView *tempImageView = [[UIImageView alloc]initWithFrame:presentationDisplay.frame];

        int newLayerCount = 0;

        // Start a search for the layer in the list of old layers
        for (NSString *obj in tempLayerNames)
        {
            if([obj isEqualToString:layerName])
            {
                // NSLog(@"Found Layer : %@", layerName);

                [layerNames addObject:obj];
                tempImage = [tempLayerImages objectAtIndex:newLayerCount];
                [layerImages addObject:tempImage];

                isFound = YES;
                break;
            }
            newLayerCount++;
            // This layer is already visiable ont he screen, do not fade it in
            tempImageView.alpha = 1.0;
        }

        if (!isFound)
        {
            // NSLog(@"Downloading Layer : %@", layerName);

//            NSURL *layerURL = [NSURL URLWithString:layerName];

//            tempImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:layerURL]];

            tempImage = [self imageFromURLInString:layerName];

            [layerNames addObject:layerName];
            if(tempImage == nil)
            {
                NSLog(@"Error - Image not fonud on server..........................................................");
                NSLog(@"Error - URL : %@", layerName);
                [layerImages addObject:[[UIImage alloc]init]];
            }
            else
            {
//                tempImageView.image = tempImage;
                [layerImages addObject:tempImage];
            }

            // Set this layer Alpha to zero, this way we can fade it in
            tempImageView.alpha = 1.0;
        }

        // NSLog(@"Image Layer : %i", layerCount);

        [tempImageView setImage:tempImage];

        [layerViewToAdd setTranslatesAutoresizingMaskIntoConstraints:YES];
        [layerViewToAdd addSubview:tempImageView];


        NSLog(@"Iterating");

        layerCount++;

        dispatch_async(dispatch_get_main_queue(), ^{

            NSNumber *tempPercentage = [NSNumber numberWithFloat: (float) (layerCount) / [currentSetupInfo[@"layers"] count]];

            [self updateSpinner:tempPercentage];
        });
    }

    return layerViewToAdd;
}


-(void)presentLayersInView:(UIView *)layerViewToAdd
{
    layerViewToAdd.alpha = 0.0f;

    [presentationDisplay setTranslatesAutoresizingMaskIntoConstraints:YES];
    [presentationDisplay addSubview:layerViewToAdd];


    UIView *layerViewToRemove;


    if(layerViewTag != 0)
    {
        layerViewToRemove = [presentationDisplay viewWithTag:layerViewTag];
        [presentationDisplay sendSubviewToBack:layerViewToRemove];
        // Swap the number used for the TAG (will toggle between 1 and -1)
        layerViewTag = layerViewTag * -1;
        layerViewToAdd.tag = layerViewTag;
    }
    else
    {
        // Fist time setup
        layerViewTag = 1;
        layerViewToAdd.tag = layerViewTag;
    }

    layerViewToRemove.alpha = 0.0;
    layerViewToAdd.alpha = 1.0f;
    presentationDisplay.alpha = 1.0;

    [layerViewToRemove removeFromSuperview];
    [self stopSpinner];
}

1 个答案:

答案 0 :(得分:0)

我在几天后想出来了......

因此,layerNames和layerImages都是NSMutableArrays,但是,在代码的早期,我设法为他们注释掉了Alloc Init。

最终结果是,在iOS6中运行良好,在iOS7中有奇怪的结果。添加了这部分,它第一次工作正常。

对自己很生气.........有点担心它能干活了!