【问题标题】:Adding object to multiple views将对象添加到多个视图
【发布时间】:2012-02-05 14:39:29
【问题描述】:

我有一个 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;
    }


}

【问题讨论】:

    标签: iphone objective-c ios uiview


    【解决方案1】:

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

    如果您的所有视图都具有相似的变换,那么您可能会更幸运地使用 CAReplicatorLayer 之类的东西,它是一个自动创建具有不同变换的 CALayer 副本的系统。

    这只有在你的视图都排列成网格或圆圈或其他东西时才有效。如果它们只是随机点缀,那将无济于事。

    如果您尝试绘制超过 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];            
        }
    

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

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

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

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

    【讨论】:

    • 我认为子类化和静态变量的工作方式与您认为的不同。如果您对多个视图有相同的转换,那么它们都将位于屏幕上的同一位置(即使您可以多次添加相同的视图,但您不能)。如果它们在不同的地方,它们需要是不同的对象。
    • 另一种选择是自己在 drawRect: 或类似的内部绘制图像。
    • 应用转换不太可能成为瓶颈。它实际上是在渲染转换后的视图,这需要时间。我可能错了,如果您的变换非常复杂,请尝试只生成一次变换并将其设置为静态 CSTransform3D 或 CGAffineTransform 变量,但我说,我怀疑这就是它缓慢的地方。您可以随时在问题中添加一些代码示例以获得更具体的帮助。
    • @Jesse:Core Graphics 比 Core Animation 慢很多,所以如果 core 动画太慢,我怀疑 drawRect 会更快(Core Graphics 不使用硬件加速进行变换或绘图,Core 动画虽然它仍然比纯 OpenGL 慢很多)。
    • 感谢您的更新。引脚的容器位于滚动视图中。当我使用 scrollView 放大时,我需要引脚保持在其容器视图中的相同位置,但它们需要缩放更小,因此在放大时它们在屏幕上的大小似乎相同 - 如果这有意义的话。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多