2012-02-05 88 views
0

我有一个名为PinView的UIView的子类,它包含一个图像。基本上PinView被多次添加到我的应用程序,然后我对PinView对象执行转换。问题是,当我添加很多PinView时,我的应用程序变慢,因为我正在转换每个PinView。将对象添加到多个视图

理想情况下,我想有一个“静态” PinView是被添加到一个UIView多次,但我只需要一次改变它。目前这似乎并不奏效。每次我将静态PinView添加到我的UIView中时,它只会出现在UIView中一次(由于它只能够有一个我猜测的超级视图)。

我很难找到解决这个问题的最佳途径 - 我如何使用一个PinView的单个指针,多次添加到一个UIView,并能够在PinView上执行变换在我的UIView中显示的PinViews? (顺便说一下,所有PinView的变换总是相同的)。

林假定这将是获得的性能提升的最佳途径,如果不是请让我知道的情况。

UPDATE:

- (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; 

    } 


} 

UPDATE:

去掉上面的,现在只是有:

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

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


} 

回答

2

这不能做,我害怕。每个UIView实例只能添加到屏幕一次。

如果你所有的观点也有类似的变换,你可能会使用类似CAReplicatorLayer,这是自动创建具有不同的变换CALayers的副本系统有更多的运气。

这只会在你的视图全部排列成网格或圆形或其他东西时才起作用。如果他们只是随机点缀,这将无济于事。

如果你想吸引超过100个浏览,你可能只是都撞在Core Animation的基本性能的天花板iOS上。

下一个途径试图将使用OpenGL绘制你的脚,可能使用像SparrowCocos2D库来简化绘制多个变换图像用OpenGL(我建议麻雀,因为它集成了其它的UIKit控制好 - 科科斯更适合游戏)。

UPDATE:

此代码是不必要的:

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而不是设置中心(可能会更快一些)来移动它们。

+0

我不认为子类化和静态变量的工作方式,你认为他们这样做。如果您对多个视图有相同的转换,那么它们将全部位于屏幕上的相同位置(即使您可以多次添加相同的视图,但不能这样做)。如果他们在不同的地方,他们需要成为不同的对象。 – 2012-02-05 15:35:04

+0

另一种选择是在drawRect:或类似的内部自己绘制图像。 – 2012-02-05 15:48:27

+0

应用转换不可能是瓶颈。它实际上是渲染需要时间的转换视图。我可能是错的,如果你的变换非常复杂,试着只生成一次变换,并将其设置为一个静态的CSTransform3D或CGAffineTransform变量,但是我认为,我怀疑它的速度很慢。您可以随时在您的问题中添加一些代码示例以获得更具体的帮助。 – 2012-02-05 15:48:48