2009-01-04 40 views
11

Có các phương pháp để chuyển CGPoint từ một UIView sang một UIView khác và từ CALayer này sang CAL khác. Tôi không thể tìm cách thay đổi CGPoint từ hệ tọa độ của UIView thành hệ thống tọa độ của CALayer.Chuyển đổi CGPoint từ hệ tọa độ UIView sang hệ tọa độ CALayer

Lớp và chế độ xem máy chủ có cùng hệ tọa độ không? Tôi có cần phải chuyển đổi điểm giữa chúng không?

Cảm ơn, Corey

[EDIT]

Cảm ơn câu trả lời! Thật khó để tìm thông tin về sự khác biệt/điểm tương đồng giữa CA trên iPhone và Mac. Tôi ngạc nhiên vì tôi không thể tìm thấy vấn đề này được giải quyết trực tiếp trong bất kỳ Tài liệu Apple nào.

Tôi đang theo đuổi câu trả lời này để trợ giúp về lỗi, tôi đang khắc phục sự cố và đây là dự đoán tốt nhất của tôi, nhưng tôi cho rằng tôi đang sủa cây sai. Nếu hệ thống phối hợp là như nhau, sau đó tôi có một vấn đề khác ...

Vấn đề thực tế Tôi gặp có thể được tìm thấy ở đây trên Stack Overflow: layer hit test only returning layer when bottom half of layer is touched

Trả lời

4

Bạn có thể đặt thuộc tính transform của CALayers thành biến đổi thích hợp nếu bạn muốn lật hệ tọa độ của mình, nhưng lưu ý rằng điều này có thể sẽ lật bản vẽ của chúng về contents (tôi chưa thử nghiệm điều đó, nhưng nó có ý nghĩa điều này sẽ đúng). Xác nhận của tôi rằng các CALayer liên kết với một UIView chia sẻ cùng một hệ thống tọa độ có thể trong thực tế là hoàn toàn sai lầm. Nó cũng có thể là CALayers sử dụng cùng một hệ tọa độ như UIViews (nghĩa là chúng không bao giờ lộn theo chiều dọc), nhưng tôi nghĩ chúng là vì CoreGraphics sử dụng một hệ tọa độ lộn xộn tương đối so với UIKit.

Một cách đơn giản để kiểm tra là thêm một lớp CALayer có kích thước màn hình làm lớp con của lớp của khung nhìn, sau đó thêm một CALayer nhỏ khác làm lớp con của lớp đó. Bạn có thể thiết lập nó để hiển thị tại (0, 0, 320, 100) và xem nếu nó xuất hiện trên đầu hoặc dưới cùng của màn hình của iPhone. Điều này sẽ cho bạn biết trong đó hướng trục Y đi cho 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]; 
} 

Tôi vừa thực hiện kiểm tra này và xuất hiện CALayers thực sự sử dụng cùng một hệ tọa độ như UIViews, vì vậy xác nhận của tôi rằng đảo ngược trục Y chắc chắn là sai. Tuy nhiên, nếu bạn vẽ trực tiếp với CoreGraphics, hãy lưu ý rằng CoreGraphics dùng sử dụng trục Y lật (mặc dù khi vẽ trong lớp con UIView hoặc, tôi giả định, một đại biểu CALayer, ngữ cảnh CoreGraphics đã được lật để khớp với UIView's (hoặc hệ thống tọa độ) của CALayer).

Vì vậy, câu trả lời ngắn gọn, nếu bạn thực hiện điều này ở xa, hệ thống tọa độ cho CALayer phải khớp với hệ tọa độ cho UIView tương ứng của nó.

+0

Kevin, nếu bạn có thời gian, bạn sẽ quan tâm đến chủ đề chính được liệt kê trong bài đăng của tôi bên dưới. Bạn có vẻ khá am hiểu về điều này và mọi hiểu biết đều được đánh giá cao. Cảm ơn một lần nữa –

-2

Tôi tin rằng hai có cùng một hệ tọa độ.

0

Tôi tin rằng hệ tọa độ của UIView và lớp liên quan của nó phải giống nhau. Tuy nhiên, nếu bạn tự tạo lớp, hệ tọa độ được lật theo chiều dọc.

13

Các tài liệu cho hitTest nói:

/* 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. */ 

Vì vậy, bạn cần phải làm gì (một cái gì đó như thế này):

CGPoint thePoint = [touch locationInView:self]; 
thePoint = [self.layer convertPoint:thePoint toLayer:self.layer.superlayer]; 
CALayer *theLayer = [self.layer hitTest:thePoint]; 
+0

Điều này là lạ bởi vì 'self.layer' thực sự là một lớp gốc, vì vậy nó sẽ không có' superlayer'. Nhưng nó thực sự hoạt động. Cảm ơn! – Rizo

1

Từ bài kiểm tra của tôi, tôi đã phát hiện ra rằng lớp con chia sẻ cùng một hệ tọa độ vì đó là lớp cha và do đó nếu bạn thêm lớp con vào lớp UIView thì chúng sẽ chia sẻ cùng một hệ tọa độ.

Trong trường hợp bạn vẫn muốn lật hệ tọa độ để nguồn gốc của nó nằm ở góc trên bên trái, bạn nên sử dụng phép biến đổi này để lật trục y. (x, y, 1) = (x ', y', 1) * [1 0 0], [0 -1 0], [0 heigth 1]

được dịch sang mã là: [your_layer setAffineTransform: CGAffineTransformMake (1,0,0, -1,0, heigth)];

4

Về tài liệu Apple, tôi đã tìm thấy "Lưu ý hệ điều hành iPhone" trong phần Hệ thống điều phối lớp của Core Animation Programming Guide (2008-11-13).

Lớp gốc mặc định của phiên bản UIView sử dụng hệ tọa độ lật khớp với hệ tọa độ mặc định của trường UIView – nguồn gốc ở trên cùng bên trái và giá trị tăng và sang phải. Các lớp được tạo bởi instantiating CALayer trực tiếp sử dụng hệ tọa độ Core Animation tiêu chuẩn.

0
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; 
} 
Các vấn đề liên quan