简体   繁体   English

使子视图从另一个子视图“后面”降序

[英]make subview descend from “behind” another subview

Within a UISrollView , I have several programmatically-added subviews representing nodes in a tree: UISrollView ,我有几个以编程方式添加的子视图,它们表示树中的节点:

在此处输入图片说明

Each node's frame includes the node itself plus the line connecting it to its parent. 每个节点的框架包括节点本身以及将其连接到其父节点的线。 (I did this to facilitate animation of the line with the node.) In the picture below, the frame is drawn for one of the nodes: (我这样做是为了便于对带有节点的线进行动画处理。)在下图中,为其中一个节点绘制了框架:

在此处输入图片说明

When the user taps on one of the nodes, two child nodes are "born". 当用户点击节点之一时,两个子节点“出生”。 I'd like to animate this by having the child nodes descend down from behind the parent node. 我想通过让子节点从父节点的后部向下下降来对此进行动画处理。 My basic animation code is: 我的基本动画代码是:

- (void)descendFromParent
{
    // Do nothing if this is root node
    if (!self.parent)
        return;

    // Move node to parent location
    self.frame = CGRectMake(self.frame.origin.x + self.parent.nodeFrame.origin.x - self.nodeFrame.origin.x,
                            self.frame.origin.y + self.parent.nodeFrame.origin.y - self.nodeFrame.origin.y,
                             self.frame.size.width, self.frame.size.height);

    // Animate the move back to original location
    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:0
                     animations:^{
                         self.frame = self.trueFrame;
                     }
                     completion:nil];
}

( nodeFrame is a frame containing just the circular part of the view.) nodeFrame是仅包含视图的圆形部分的框架。)

The problem of course is that as the child node is descending, it (especially the line) is visible on top of and above the parent node: 当然,问题在于当子节点下降时,它(特别是该行)在父节点的上方和上方可见:

在此处输入图片说明

I've tried a lot of different ways to make this work -- using CGContextClip , etc. -- but none of them work, mainly because drawRect: isn't called during the animation. 我尝试了许多不同的方法来实现此目的-使用CGContextClip等-但它们都不起作用,主要是因为在动画期间未调用drawRect:

How can I make this work? 我该如何进行这项工作?

You may want to look at the UIView methods 您可能想看看UIView方法

  • -insertSubview:belowSubview:
  • -insertSubview:atIndex:
  • -sendSubviewToBack:

In your case, you can either send the two subviews to the background with -sendSubviewToBack: after you have added them. 对于您的情况,可以在添加两个子视图后使用-sendSubviewToBack:将其发送到后台。 Or you can just add them with -insertSubview:atIndex: and provide 0 as the index. 或者,您可以仅使用-insertSubview:atIndex:添加它们,并提供0作为索引。

I think your problem is not how to arrange the views in the correct view hierarchy, but the following: 我认为您的问题不是如何按正确的视图层次结构排列视图,而是以下内容:

After you have arranged the child disks behind the parent disk, you want them to slide down, and while they are sliding, the edge that connects their centers should have first zero length (when all 3 disks are at the same place), and should then be extended until it reaches its final length in the end. 将子磁盘布置在父磁盘后面之后,您希望它们向下滑动,并且在滑动时,连接它们中心的边缘应具有第一个零长度(当所有三个磁盘都在同一位置时),并且然后进行扩展,直到最终达到其最终长度。

If this is the case, one possible solution would be: 如果是这种情况,一种可能的解决方案是:

Lets call the initial x,y center coordinate of one disk (0,0), and the final coordinate (X,Y). 让我们称一个磁盘的初始x,y中心坐标(0,0)和最终坐标(X,Y)。 Using the usual animation code, it is easy to move the child center to (X,Y) in time t. 使用常规的动画代码,很容易在时间t内将子中心移动到(X,Y)。
Now assume you have an additional image view that shows the edge along the diagonal. 现在假设您有一个附加的图像视图,该视图显示了沿对角线的边缘。 In the end position, the center of the "edge view" is at (X/2,Y/2), and its size is (X,Y). 在最终位置,“边缘视图”的中心位于(X / 2,Y / 2),其大小为(X,Y)。 If this view is placed behind all others, it will connect the two disks at their final position. 如果此视图放置在所有其他视图的后面,它将在最终位置连接两个磁盘。
The animation consists now of 1) changing the center property from the initial position (0,0) to (X/2,Y/2), and 2) changing the scale of the view (using its transform property ) from zero to the final size, also in time t. 动画现在包括1)将center属性从初始位置(0,0)更改为(X / 2,Y / 2),以及2)将视图的比例(使用其transform属性 )从零更改为最终大小,也在时间t中。
This should do it. 这应该做。

您可以为子视图指定索引,尝试在索引0处插入要设置动画的节点,并使蓝色节点在较高的索引处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM