将对象添加到多个视图 [英] Adding object to multiple views

查看:44
本文介绍了将对象添加到多个视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im have a subclass of UIView, called PinView, which contains an image. Basically PinView gets added multiple times to my app, and then I perform a transform on PinView objects. The issue is that when I add a lot of PinViews, my app gets sluggish because I am transforming each PinView.

理想情况下,我想让一个静态" PinView多次添加到UIView中,但是我只需要转换一次即可.目前,这似乎不起作用.每次我将静态PinView添加到UIView时,它都只会在UIView中出现一次(因为我只能猜测一个Superview).

Ideally, I want to have one 'static' PinView that gets added to a UIView multiple times but i only have to transform it once. Currently this doesn't seem to work. Every time I add the static PinView to my UIView, it will only ever appear in the UIView once (due to it only being able to have one superview I'm guessing).

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

Im struggle to find out the best way to go about solving this problem - how do I use a single pointer to a PinView, add it multiple times to a UIView and be able to perform a transform on the PinView which gets passed on to PinViews displayed in my UIView? (by the way, the transform is always the same for all the PinViews).

我认为这将是提高性能的最佳方法,如果不是这种情况,请告诉我.

Im assuming this will be the best way to get a performance improvement, if this is not the case please let me know.

更新:

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

    }


}

更新:

删除了上面的内容,现在只有:

Removed the above and now just have:

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

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


}

推荐答案

恐怕无法完成.每个UIView实例只能添加到屏幕一次.

This can't be done I'm afraid. Each UIView instance can only be added to the screen once.

如果所有视图都具有相似的变换,那么使用CAReplicatorLayer之类的东西可能会带来更多的运气,该系统可以自动创建具有不同变换的CALayers的副本.

If all your views have similar transforms, you might have more luck using something like CAReplicatorLayer, which is a system for automatically creating duplicates of CALayers with different transforms.

仅当您的视图全部排列成网格或圆形或类似形状时,该选项才有效.如果它们只是随机点缀,将无济于事.

That will only works if your views are all arranged in a grid or circle or something though. If they are just dotted randomly, it won't help.

如果您要绘制100多个视图,则可能只是与iOS上核心动画"的基本性能上限相抵触.

If you are trying to draw more than 100 views, you're probably just bumping up against the fundamental performance ceiling of Core Animation on iOS.

下一种尝试的方法是使用OpenGL绘制图钉,也许使用 Sparrow Cocos2D 可以简化使用OpenGL绘制多个变换图像的过程(我建议使用Sparrow,因为它可以更好地集成与其他UIKit控件配合使用-Co​​cos更适合游戏).

The next approach to try would be to use OpenGL to draw your pins, perhaps using a library like Sparrow or Cocos2D to simplify drawing multiple transformed images with OpenGL (I'd recommend Sparrow as it integrates better with other UIKit controls - Cocos is more appropriate for games).

更新:

此代码是不必要的:

    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"因此,如果您将它们分配给已知类型的变量,则无需强制转换.

The code below is sufficient, because setting the transform doesn't modify the pointer to the object, so it will update the object in the array even if the array isn't mutable, and array objects are declared as 'id' so they don't need to be cast if you assign them to a variable of a known type.

    mut = [self.annotationsDict objectForKey:identifier];

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

我还认为您可以删除 isKindOfClass:,以检查是否仅将那些数组索引用于这些对象类型.看来这是一个很好的预防措施,但是如果您一遍又一遍地循环执行,则会导致性能下降.

I would also think you can remove the isKindOfClass: check if you only ever use those array indices for those object types. It may seem like a good precaution, but it carries a performance penalty if you're doing it over and over in a loop.

但是对于10个视图,我只是不希望它这么慢.您是否尝试过而没有移动标注中心.效果更好吗?如果是这样,可以将其限制为仅显示当前的标注,还是使用CGAffineTransformTranslate而不是设置中心(可能会更快一些)来移动它们.

But for 10 views, I just wouldn't expect this to be that slow at all. Have you tried it without moving the callout centres. Does that perform better? If so, can you limit that to just the callouts that are currently visible, or move them using CGAffineTransformTranslate instead of setting the centre (which may be a bit quicker).

这篇关于将对象添加到多个视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆