将对象添加到多个视图

时间:2012-02-05 14:39:29

标签: iphone objective-c ios uiview

我有一个UIView的子类,叫做PinView,它包含一个图像。基本上PinView会多次添加到我的应用程序,然后我对PinView对象执行转换。问题在于,当我添加大量PinView时,我的应用程序变得迟钝,因为我正在转换每个PinView。

理想情况下,我希望有一个'静态'PinView多次添加到UIView,但我只需要转换一次。目前这似乎不起作用。每次我将静态PinView添加到我的UIView时,它只会出现在UIView中一次(因为它只能有一个我猜的超视图)。

我很难找到解决这个问题的最佳方法 - 如何使用指向PinView的单个指针,将其多次添加到UIView并且能够对PinView执行转换并传递给它到我的UIView中显示的PinViews? (顺便说一下,所有PinView的变换总是相同的。)

我认为这将是获得绩效改善的最佳方式,如果不是这样,请告诉我。

更新:

- (void)layoutSubviews
{
    CGAffineTransform transform = CGAffineTransformMakeScale(1.0/self.zoomValue, 1.0/self.zoomValue);
    NSMutableArray *mut = nil;
    PinView *pinView = nil;
    CallOutView *callOut = nil;

    //get all dictionary entries
    for(NSString *identifier in self.annotationsDict.allKeys){
    //get the array from dictionary
        mut = [(NSArray *)([self.annotationsDict objectForKey:identifier]) mutableCopy];        
        //change layout if not nil
        if([[mut objectAtIndex:PIN] isKindOfClass:[PinView class]]){
            pinView = ((PinView *)[mut objectAtIndex:PIN]);
            pinView.transform = transform;
            [mut replaceObjectAtIndex:PIN withObject:pinView];            
        }
        if([[mut objectAtIndex:CALL_OUT] isKindOfClass:[CallOutView class]]){
            callOut = ((CallOutView *)[mut objectAtIndex:CALL_OUT]);
            callOut.transform = transform;
            [mut replaceObjectAtIndex:CALL_OUT withObject:callOut];
            if(pinView !=nil)callOut.center = CGPointMake(pinView.center.x, pinView.center.y - pinView.frame.size.height);
        }

        [self updateAnnotationsKey:identifier forObject:[NSArray arrayWithArray:mut]];

        mut = nil;
        pinView = nil;
        callOut = nil;

    }


}

更新:

删除了以上内容,现在只需:

- (void)layoutSubviews
{
    CGAffineTransform transform = CGAffineTransformMakeScale(1.0/self.zoomValue, 1.0/self.zoomValue);

    for(UIView *view in self.subviews){
        view.transform = transform;
    }


}

1 个答案:

答案 0 :(得分:2)

我担心这不可能。每个UIView实例只能添加到屏幕一次。

如果你的所有观点都有类似的变换,你可能会更幸运地使用像CAReplicatorLayer这样的系统,这是一个自动创建具有不同变换的CALayers重复的系统。

仅当您的视图全部以网格或圆形或其他方式排列时,这才有效。如果它们只是随机点缀,它将无济于事。

如果您尝试绘制超过100个视图,那么您可能只是碰到了iOS上Core Animation的基本性能上限。

下一个尝试的方法是使用OpenGL绘制您的引脚,可能使用像SparrowCocos2D这样的库来简化使用OpenGL绘制多个变换图像(我推荐使用Sparrow)与其他UIKit控件更好地集成--Cocos更适合游戏)。

更新:

此代码是不必要的:

    mut = [(NSArray *)([self.annotationsDict objectForKey:identifier]) mutableCopy];

    if([[mut objectAtIndex:PIN] isKindOfClass:[PinView class]]){
        pinView = ((PinView *)[mut objectAtIndex:PIN]);
        pinView.transform = transform;
        [mut replaceObjectAtIndex:PIN withObject:pinView];            
    }

下面的代码就足够了,因为设置转换不会修改指向对象的指针,因此即使数组不可变,它也会更新数组中的对象,并且数组对象被声明为'id'因此,如果将它们分配给已知类型的变量,则不需要进行强制转换。

    mut = [self.annotationsDict objectForKey:identifier];

    if([[mut objectAtIndex:PIN] isKindOfClass:[PinView class]]){
        pinView = [mut objectAtIndex:PIN];
        pinView.transform = transform;
    }

如果您只对这些对象类型使用这些数组索引,我还认为您可以删除isKindOfClass:检查。这似乎是一个很好的预防措施,但如果你在一个循环中反复这样做,它会带来性能损失。

但是对于10个观点,我根本不会指望它会那么慢。您是否在不移动标注中心的情况下尝试过它。那表现更好吗?如果是这样,你可以将其限制为当前可见的标注,或者使用CGAffineTransformTranslate移动它们而不是设置中心(可能会更快一些)。