将对象添加到多个视图
我有一个名为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;
}
}
这不能做,我害怕。每个UIView实例只能添加到屏幕一次。
如果你所有的观点也有类似的变换,你可能会使用类似CAReplicatorLayer,这是自动创建具有不同的变换CALayers的副本系统有更多的运气。
这只会在你的视图全部排列成网格或圆形或其他东西时才起作用。如果他们只是随机点缀,这将无济于事。
如果你想吸引超过100个浏览,你可能只是都撞在Core Animation的基本性能的天花板iOS上。
下一个途径试图将使用OpenGL绘制你的脚,可能使用像Sparrow或Cocos2D库来简化绘制多个变换图像用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而不是设置中心(可能会更快一些)来移动它们。
我不认为子类化和静态变量的工作方式,你认为他们这样做。如果您对多个视图有相同的转换,那么它们将全部位于屏幕上的相同位置(即使您可以多次添加相同的视图,但不能这样做)。如果他们在不同的地方,他们需要成为不同的对象。 – 2012-02-05 15:35:04
另一种选择是在drawRect:或类似的内部自己绘制图像。 – 2012-02-05 15:48:27
应用转换不可能是瓶颈。它实际上是渲染需要时间的转换视图。我可能是错的,如果你的变换非常复杂,试着只生成一次变换,并将其设置为一个静态的CSTransform3D或CGAffineTransform变量,但是我认为,我怀疑它的速度很慢。您可以随时在您的问题中添加一些代码示例以获得更具体的帮助。 – 2012-02-05 15:48:48