Сложенные слои UIView не перемещаются - PullRequest
2 голосов
/ 17 января 2009

Я разрабатываю приложение для iPhone, которое перемещает слой UIView между другими слоями UIView на основе акселерометра.

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

updateInterval равен 60, и я использую метод drawAtPoint: метод UIView для перемещения слоя.

Мой вопрос: есть ли свойство UIView, такое как opaque, clipsToBounds и т. Д., Которое необходимо включить для точного перемещения на основе акселерометра смещенного UIView?

Заранее благодарим за любую помощь, которую вы можете оказать.

Обновление:

Нижний слой непрозрачный, а слои выше - прозрачные PNG.

У меня проблемы с доступом к свойству фрейма UIView. Вот код из моего Object2D класса:

- (id)initWithImage:(NSString*)imageName
{
    if (self = [super init])
    {
        position = [[Point2D alloc] init];
        vector = [[Vector2D alloc] init];
        imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]; 
        myImageObj = [[UIImage alloc] initWithContentsOfFile:imagePath]; 
        size.width = myImageObj.size.width;
        size.height = myImageObj.size.height;
    }

    return self;
}

А вот метод класса * original draw:, который вызывается из класса ViewController:

- (void)draw
{
    [myImageObj drawAtPoint:CGPointMake( position.X, position.Y ) ];
    [ self setNeedsDisplay ];
}

Я пробовал разные способы доступа к свойству фрейма, но безрезультатно:

myImageObj.frame = CGRectMake(position.X, position.Y, size.width, size.height);
myImageObj.CGImage.frame.y = position.Y;

Изучение документации по API показывает, что первый способ будет работать, но это не так.

Знаете ли вы, как получить доступ к свойству фрейма UIView?

Заранее спасибо.

Ответы [ 3 ]

4 голосов
/ 20 января 2009

Вы не можете установить отдельные параметры кадра напрямую. Вы должны создать новый CGRect и установить фрейм к этому CGRect. Существуют различные способы изменить параметры CGRect после его создания.

CGRect myNewFrame = someView.frame;

myNewFrame.origin.x = 1.0;

myNewFrame.size = CGSizeMake(100.0f, 50.0f);

someView.frame = myNewFrame;

Идея состоит в том, чтобы установить CGRect так, как вы хотите, а затем установить для свойства frame вид этого CGRect, тогда ваш товар.

Что касается UIView ... У вас может быть несколько проблем. Во-первых, как сказано выше, метод drawAtPoint стоит дорого. Во-вторых, а может быть и хуже, у вас есть несколько прозрачных изображений. Прозрачность - одна из самых дорогих операций на iPhone, на самом деле, в инструментах есть проверка именно для этого. Вы должны избегать прозрачности любой ценой. Несколько прозрачных PNG с перерисовкой во время вращения, скорее всего, приведут к сбоям в работе приложения.

Мой следующий совет - подумать, нужен ли вам Просмотр в середине прозрачных пленок, возможно, другой слой мог бы сделать эту работу. если вам нужна сенсорная функциональность, вы можете использовать представление в корне иерархии слоев для обработки касаний. Другими словами, у вас есть это:
UIView CALayer UIView CALayer CALayer

но вы могли бы просто иметь это: UIView (теперь обрабатывать все касания) CALayer CALayer (ранее вид) CALayer CALayer

Это также поможет, поскольку у CALayers меньше накладных расходов, чем у UIViews.

Надеюсь, это поможет.

2 голосов
/ 17 января 2009

Каждый раз, когда вы используете drawAtPoint: вы заставляете UIView перерисовываться в графический слой. Это дорого.

UIView уже имеет свойство -frame, которое определяет его местоположение и размер. Обновление только местоположения позволяет графическому оборудованию перемещать уже составные слои вокруг.

Я не уверен, что вы подразумеваете под "сэндвичем", но я предполагаю, что это размещение слоев с разными z-индексами? Если это так, я предполагаю, что средний (слой, который вы перемещаете) и верхний слои должны быть прозрачными, а нижний слой должен быть непрозрачным, чтобы обеспечить его производительность.

Дайте мне знать, если это не то, что вы искали ...

1 голос
/ 20 января 2009

Я думаю, вы неправильно понимаете, как работают UIViews. Во-первых, вы хотите создать UIImageViews для размещения ваших UIImages. Затем вы хотите добавить их к одному суперпредставлению, используя его метод addSubview :. Наконец, вы хотите изменить свойство frame вашего среднего UIImageView (в блоке beginAnimations / commitAnimations, если вы хотите плавно анимировать его), чтобы оно переместилось в вашу новую позицию.

Если вы поместите ваш UIImage в инкапсулирующий UIImageView, он будет кеширован как текстура на GPU, и любое изменение в позиции UIImageView будет аппаратно ускорено. drawAtPoint:, как указал Дэн, ужасно дорог, и его следует избегать, если вы можете. Вы на правильном пути с вашим кодом myImageObj.frame = CGRectMake, его просто нужно применить к UIImageView, а не к UIImage.

Для простой трехслойной структуры, если у вас нет больших изображений, даже изображения с большой прозрачностью будут плавно анимироваться. Я сделал это для десятков прозрачных UIViews (которые являются очень легкими обертками вокруг CALayers) без заминки производительности.

Кроме того, если ваши классы Point2D и Vector2D являются просто оболочками для двумерных координат, вы можете попробовать заменить их на структуры CGPoint. Вокруг этого облегченного типа данных существует множество вспомогательных функций.

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