Преобразование CGPoint из системы координат UIView в систему координат CALayer - PullRequest
11 голосов
/ 04 января 2009

Существуют методы для передачи CGPoint из одного UIView в другой и из одного CALayer в другой. Я не могу найти способ изменить CGPoint из системы координат UIView на систему координат CALayer.

Имеет ли слой и его главное представление одинаковую систему координат? Нужно ли преобразовывать точки между ними?

Спасибо, Corey

[EDIT]

Спасибо за ответ! Трудно найти информацию о различиях / сходствах между CA на iPhone и Mac. Я удивлен, что не смог найти эту проблему, адресованную напрямую ни в одной документации Apple.

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

Фактическую проблему, с которой я столкнулся, можно найти здесь, в Переполнении стека: проверка попадания слоя, возвращающая слой только при касании нижней половины слоя

Ответы [ 7 ]

13 голосов
/ 25 февраля 2009

Документация для hitTest гласит:

/* Returns the farthest descendant of the layer containing point 'p'.
 * Siblings are searched in top-to-bottom order. 'p' is in the
 * coordinate system of the receiver's superlayer. */

Так что вам нужно сделать (что-то вроде этого):

CGPoint thePoint = [touch locationInView:self];
thePoint = [self.layer convertPoint:thePoint toLayer:self.layer.superlayer];
CALayer *theLayer = [self.layer hitTest:thePoint];
4 голосов
/ 31 июля 2009

Что касается документации Apple, я обнаружил «Примечание для iPhone OS» в разделе «Система координат слоя» в Руководстве по программированию базовой анимации (2008-11-13).

Корневой слой по умолчанию для экземпляра UIView использует перевернутую систему координат, которая соответствует системе координат по умолчанию для экземпляра UIView - источник находится в верхнем левом углу, а значения увеличиваются вниз и вправо. Слои, созданные путем создания экземпляра CALayer, напрямую используют стандартную систему координат Core Animation.

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

Вы можете установить свойство transform CALayers для соответствующего преобразования, если вы хотите перевернуть их систему координат, но учтите, что это, вероятно, также перевернет их чертеж contents (я не проверял это, но имеет смысл, что это будет правдой). Мое утверждение, что CALayer, связанный с UIView, использует одну и ту же систему координат, на самом деле может быть совершенно ошибочным. Возможно также, что CALayers используют ту же систему координат, что и UIViews (то есть они никогда не переворачиваются по вертикали), но я подумал, что это так, поскольку CoreGraphics использует перевернутую систему координат относительно UIKit.

Простой способ проверить это добавить CALayer размером с экран в качестве подслоя слоя представления, а затем добавить еще один маленький CALayer в качестве подслоя этого слоя. Вы можете установить его на (0, 0, 320, 100) и посмотреть, будет ли он отображаться в верхней или нижней части экрана iPhone. Это скажет вам, в каком направлении идет ось Y для CoreAnimation.

- (void)viewDidLoad {
  [super viewDidLoad];
  CALayer *rootLayer = [CALayer layer];
  rootLayer.frame = self.view.layer.bounds;
  CALayer *smallLayer = [CALayer layer];
  smallLayer.frame = CGRectMake(0, 0, rootLayer.bounds.size.width, 50);
  smallLayer.backgroundColor = [UIColor blueColor].CGColor;
  [rootLayer addSublayer:smallLayer];
  [self.view.layer addSublayer:rootLayer];
}

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

Таким образом, короткий ответ, если вы сделали это так далеко, это то, что система координат для CALayer должна соответствовать системе координат для соответствующего ему UIView.

1 голос
/ 30 марта 2009

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

Если вы все еще хотите перевернуть систему координат так, чтобы ее начало находилось в верхнем левом углу, вам следует использовать это преобразование, которое переворачивает ось Y. (x, y, 1) = (x ', y', 1) * [1 0 0], [0 -1 0], [0 высота 1]

что в переводе на код: [your_layer setAffineTransform: CGAffineTransformMake (1,0,0, -1,0, высота)];

0 голосов
/ 05 июля 2012
Methods that fixing frames and points
- (CGRect) fixRect:(CGRect)rect inRect:(CGRect)container
{
    CGRect frame = rect;
    frame.origin.y = container.size.height - frame.origin.y - frame.size.height;
    return frame;
}
- (CGPoint) fixPoint:(CGPoint)point fromPoint:(CGSize)containerSize
{
    CGPoint frame = point;
    frame.y = size.height - frame.y;
    return frame;
}
0 голосов
/ 05 января 2009

Я считаю, что система координат UIView и связанный с ней слой должны быть одинаковыми. Однако, если вы создаете слои самостоятельно, система координат переворачивается вертикально.

0 голосов
/ 04 января 2009

Я полагаю, что они имеют одинаковую систему координат.

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