Добавление объекта в несколько представлений - PullRequest
0 голосов
/ 05 февраля 2012

У меня есть подкласс UIView, называемый PinView, который содержит изображение. По сути, PinView добавляется несколько раз в мое приложение, а затем я выполняю преобразование объектов PinView. Проблема в том, что когда я добавляю много PinViews, мое приложение становится вялым, потому что я трансформирую каждый PinView.

В идеале я хочу иметь один «статический» PinView, который добавляется в UIView несколько раз, но мне нужно преобразовать его только один раз. В настоящее время это не похоже на работу. Каждый раз, когда я добавляю статический PinView в свой UIView, он будет отображаться в UIView только один раз (так как я предполагаю, что у него будет только один суперпредставление).

Я изо всех сил пытаюсь найти лучший способ решить эту проблему - как я могу использовать один указатель на PinView, добавить его несколько раз в UIView и иметь возможность выполнить преобразование для PinView, которое передается дальше в PinViews отображается в моем UIView? (кстати, преобразование всегда одинаково для всех 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;
    }


}

1 Ответ

2 голосов
/ 05 февраля 2012

Боюсь, этого нельзя сделать.Каждый экземпляр UIView можно добавить на экран только один раз.

Если все ваши представления имеют похожие преобразования, вам может повезти, если вы используете что-то вроде CAReplicatorLayer, который представляет собой систему для автоматического создания дубликатов CALayers с различными преобразованиями.

Это будет работать только в том случае, если все ваши виды расположены в виде сетки, круга или чего-то еще.Если они просто расставлены случайным образом, это не поможет.

Если вы пытаетесь нарисовать более 100 видов, вы, вероятно, просто столкнетесь с фундаментальным потолком производительности Core Animation на iOS.

Следующим подходом будет использование OpenGL для рисования ваших выводов, возможно, с использованием библиотеки, такой как Sparrow или Cocos2D , чтобы упростить рисование нескольких преобразованных изображений с помощью OpenGL (I ').Я рекомендую 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:, если вы когда-либо используете thиндексы массива ose для этих типов объектов.Это может показаться хорошей мерой предосторожности, но это приводит к снижению производительности, если вы делаете это снова и снова в цикле.

Но для 10 представлений я просто не ожидал бы, что это будет так медленновсе.Вы пробовали это, не перемещая центры выноски.Это работает лучше?Если это так, вы можете ограничить это только выносками, которые в данный момент видны, или переместить их, используя CGAffineTransformTranslate вместо установки центра (что может быть немного быстрее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...