تحويل CGPoint من UIView تنسيق النظام إلى نظام الإحداثيات CALayer

StackOverflow https://stackoverflow.com/questions/410278

سؤال

وهناك طرق لنقل CGPoint من UIView واحد لآخر، ومن CALayer واحد إلى آخر. لا أستطيع أن أجد وسيلة لتغيير CGPoint من تنسيق النظام UIView لتنسيق النظام CALayer ل.

هل طبقة ووجهة نظر المضيفة لها نفس نظام الإحداثيات؟ هل أنا بحاجة إلى تحويل نقاط بينهما؟

وشكرا، كوري

[تحرير]

وشكرا على الجواب! ومن الصعب العثور على معلومات حول الاختلافات / التشابه بين CA على اي فون وماك. أنا مندهش لم استطع العثور على هذه المسألة موجهة بشكل مباشر في أي وثائق أبل.

وكنت متابعة هذه الإجابة للمساعدة في خلل وأنا استكشاف الأخطاء وإصلاحها، وكان هذا حتى الآن أفضل تخمين لي، لكنني أفترض أنا ينبح حتى الشجرة خاطئة. إذا كانت أنظمة تنسيق هي نفسها، ثم لدي قضية أخرى ...

والقضية الفعلية أواجه يمكن العثور هنا على تجاوز المكدس: ضرب اختبار فقط عودة طبقة عند لمس النصف السفلي من طبقة

هل كانت مفيدة؟

المحلول

ويمكنك تعيين الخاصية transform من CALayers لمناسبة تحويل اذا كنت ترغب في الوجه تنسيق النظام الخاص بهم، ولكن لاحظ أن هذا الأمر ربما الوجه رسمهم للcontents كذلك (أنا لم تختبر ذلك، ولكن من المنطقي أن هذا من شأنه أن يكون صحيحا). تأكيدي أن CALayer المرتبطة أسهم UIView نفس نظام الإحداثيات يمكن أن تكون في الواقع خاطئة كليا. ويمكن أيضا أن يكون ذلك CALayers استخدام نفس نظام الإحداثيات كما UIViews (أي انهم لم انقلبت عموديا)، ولكن أعتقد أنهم كانوا منذ CoreGraphics يستخدم انقلبت نظام الإحداثيات نسبة إلى UIKit.

وهناك طريقة بسيطة لاختبار سيكون إضافة CALayer الشاشة الحجم باعتبارها طبقة فرعية من طبقة وجهة نظر، ثم إضافة CALayer آخر صغير كما طبقة فرعية من ذلك. هل يمكن تعيينها لتظهر في (0، 0، 320، 100) ومعرفة ما اذا كان يظهر في الجزء العلوي أو السفلي من شاشة آي فون. هذا وسوف اقول لكم في أي اتجاه محور 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 المناظر له.

نصائح أخرى

وثائق 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];

في شروط وثائق أبل، وجدت "آي فون OS ملاحظة" في طبقة تنسيق قسم نظام في الأساسية الرسوم المتحركة البرمجة دليل (2008-11-13).

<اقتباس فقرة>   

والطبقة الجذر الافتراضية مثيل UIView تستخدم نظام إحداثيات انقلبت يطابق النظام الافتراضي لUIView مثيل أصل التنسيق في أعلى اليسار والقيم تزيد إلى الأسفل وإلى اليمين. الطبقات التي أنشأتها instantiating CALayer استخدام مباشرة الرسوم المتحركة الأساسية القياسية تنسيق النظام.

ومن بلدي التجارب لقد وجدت أن الطبقات الفرعية تتقاسم نفس نظام الإحداثيات كما انها طبقة الأم وبالتالي إذا كنت تقوم بإضافة طبقة فرعية لطبقة UIView ثم أنها سوف تشترك في نفس تنسيق النظام.

في حال كنت لا تزال ترغب في الوجه نظام تنسيق بحيث انها الأصل في الزاوية اليسرى العليا يجب عليك استخدام هذا التحول أن تقلب المحور ص. (س، ص، 1) = (س '، ذ'، 1) * [1 0 0] [0 -1 0]، [0 heigth 1]

والتي ترجمت إلى رمز هو: [your_layer setAffineTransform: CGAffineTransformMake (1،0،0، -1،0، heigth)].

وأعتقد أن نظام الإحداثيات من UIView وطبقة المرتبطة بها يجب أن تكون هي نفسها. ومع ذلك، إذا قمت بإنشاء طبقات نفسك، وانقلبت على نظام الإحداثيات عموديا.

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

وأعتقد أن لهما نفس نظام الإحداثيات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top