Manipulating the Layer Hierarchy 操作layer結構

原文

Layers come with a full set of methods for reading and manipulating the layer hierarchy, parallel to the methods for reading and manipulating the view hierarchy. A layer has a superlayer property and a sublayers property, and these methods:
? addSublayer:
? insertSublayer:atIndex:
? insertSublayer:below:,insertSublayer:above: ? replaceSublayer:with:
? removeFromSuperlayer
Unlike a view’s subviews property, a layer’s sublayers property is writable; thus, you can give a layer multiple sublayers in a single move, by assigning to its sublayers property. To remove all of a layer’s sublayers, set its sublayers property to nil.
Although a layer’s sublayers have an order, reflected in the sublayers order and regu‐ lated with the methods I’ve just mentioned, this is not necessarily the same as their back- to-front drawing order. By default, it is, but a layer also has a zPosition property, a CGFloat, and this also determines drawing order. The rule is that all sublayers with the same zPosition are drawn in the order they are listed among their sublayers siblings, but lower zPosition siblings are drawn before higher zPosition siblings. (The default zPosition is 0.)
Sometimes, the zPosition property is a more convenient way of dictating drawing order than sibling order is. For example, if layers represent playing cards laid out in a solitaire game, it will likely be a lot easier and more flexible to determine how the cards overlap by setting their zPosition than by rearranging their sibling order. Moreover, a subview’s layer is itself just a layer, so you can rearrange the drawing order of subviews by setting the zPosition of their underlying layers. In our code constructing Figure 3-5, if we assign the image view’s underlying layer a zPosition of 1, it is drawn in front of the red (left) rectangle:
[mainview addSubview:iv];
iv.layer.zPosition = 1;
Methods are also provided for converting between the coordinate systems of layers within the same layer hierarchy:
convertPoint:fromLayer:,convertPoint:toLayer:
convertRect:fromLayer:,convertRect:toLayer:

翻譯

layers 伴隨著一堆方法用來讀取和操作layer的結構。和讀取以及操作View的方法平行。一個layer有他的父layer和他所有的子layer的所有屬性和方法。
addSublayer:

  • insertSublayer:atIndex:
  • insertSublayer:below:,insertSublayer:above:
  • replaceSublayer:with:
  • removeFromSuperlayer

不同于子View的屬性,一個layer的子layer的屬性是可寫的。所以你可以給layer的多個子layer一些簡單的操作通過分配子layer的屬性。去清空所有子layer,設置子layer的屬性為nil。

雖然一個layer的子layer有一個順序,反映在子layer的順序和我剛才提到的方法的調節。這不是必須和從后面到前面的繪制順序一樣。默認情況是這樣的,但是一個layer同樣有一個zPositon的屬性,他是一個CGFloat類型,他同樣確定了繪制的順序。他的規則是具有相同zPosition屬性的按照他們的兄弟視圖列出的順序繪制,但是比他們zPosition低的在高的視圖前面。(他們的默認值是0)

有時候,zPosition屬性是一個更加方便的方法相比兄弟排序。比如,如果想表現出打牌游戲攤開牌的情景,它將更加容易和靈活的確定牌應該怎么覆蓋,通過設置他們的zPosition相對于重新設置他們的兄弟順序。此外,一個子View的layer本身就是一個layer,所以你可以重新排列子view的繪制順序通過設置他們的基本layer的zPosition。在我們的代碼中如Figure 3-5,如果我們分配一個imageView 的基本zPosition為1,他將被畫在前面。

UIImageView* iv =[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"boy"]];
    CGRect r = iv.frame;
    r.origin = CGPointMake(180,180);
    iv.frame = r;
    [self.view addSubview:iv];
    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(170, 170, 90, 90)];
    view.backgroundColor = [UIColor redColor];
    [self.view addSubview:view];
    iv.layer.zPosition = 1;


  • convertPoint:fromLayer:
  • convertPoint:toLayer:
  • convertRect:fromLayer:
  • convertRect:toLayer:
    這四個方法試了,發現位置沒有多大的變化。不知道具體該怎么用?

后在stackflow看到別人的回答

Every UIView has its own coordinates system. So if you have a UIView_1 that contains another UIView_2, they both have a point (10,10) within them.

  • 每一個UIView都有一個自己的坐標定位,所以如果你有一個UIView_1包含了另一個UIView_2,他們都有內部坐標(10,10)。
    convertPoint:toView: allows the developer to take a point in one view and convert the point to another view coordinate system.
  • 讓開發者把當前視圖的點移動到另一個視圖的坐標系當中。
    Example: view1 contains view2. The top left corner of view2 is located at view1 point (10,10), or better to say view2.frame.orgin = {10,10}. That {10,10} is based in the view1 coordinate system. So far so good.
  • 例如:view1 包含了View2.View2左上角的坐標在View1的(10,10)坐標點上.
    The user touches the view2 at point {20,20} inside the view2. Now those coordinates are in the view2 coordinate system. You can now use covertPoint:toView: to convert {20,20} into the coordinate system of view1. touchPoint = {20,20}
  • 用戶點擊坐標點View2{20,20},現在他的坐標點在view2的坐標系中。你可以用covertPoint:toView。去改變作為View1坐標系中的{20,20}。
    CGPoint pointInView1Coords = [view2 convertPoint:touchPoint toView:view1];
    So now pointInView1Coords should be {30,30} in the view1 coordinate systems. Now that was just simple math on this example, but there are all sorts of things that contribute to the conversion. Transforms and scaling come to mind.
CGPoint pointInView1Coords = [view2 convertPoint:touchPoint toView:view1];
  • 所以pointInView1Coords的坐標在View1中變成了{30,30},現在這只是一個簡單的數學例子,但是這是所有的轉換。
    Read about UIView frame, bounds, and center. They are all related and they deal with coordinate systems for a view. Its confusing until you start doing stuff with them. Remember this frame and center are in the parent's coordinate system. Bounds is in the view's coordinate system.
    閱讀關于UIView的frame,bounds,和Center。他們都關系到處理這個View的坐標。他使人困惑直到你開始使用他們。記住frame和Center 在他們父視圖的坐標中。bounds體現在她自己的坐標系中。
    John

小結

** 看了之后才知道這不是用來改變View的而是用來計算坐標點距離的。果然code比文字能更好的說明問題。**

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容