子视图的子图层重叠较高的子视图

时间:2015-04-29 17:33:46

标签: ios objective-c uiview

我遇到了一个问题:我正在创建一个从方法返回的UIView,而且该部分很好,但我注意到的是当我将子图层添加到其中一个时在子视图中,这些图层重叠在层次结构中较高的子视图(textView和imageView),添加到testViewCopy的子图层显示在这些子视图的顶部,并且它们不应该出现。我不知道在这里发生了什么导致这种情况。

代码:

- (void)makeShareImages
{
    UIView *shareView = [self shareView];

    UIView *testViewCopy = [shareView viewWithTag:0];

    NSUInteger currentIndex = 1;

    for (NSDictionary *sub in self.array)
    {
        NSArray *lastArray = [sub objectForKey:@"LastArray"];

        for (NSDictionary *dict in lastArray)
        {
            @autoreleasepool
            {
                currentIndex ++;

                CircleLayer *layer = [[CircleLayer alloc]init];
                layer.portrait = [[dict objectForKey:@"Portrait"]boolValue];

                layer.frame = testViewCopy.bounds;

                [testViewCopy.layer addSublayer:layer];

                NSData *frameData = [self getSnapshotDataFromView:shareView];

                NSString *savePath = [NSString stringWithFormat:@"%@/%lu.png",somePath,(unsigned long)currentIndex];

                [frameData writeToFile:savePath options:0 error:nil];
            }
        }
    }
}

- (UIView *)shareView
{
    UIColor *bgColor = self.containerView.backgroundColor;

    CGSize size = self.containerView.bounds.size;

    UIView *viewToShare = [[UIView alloc]init];
    viewToShare.backgroundColor = bgColor;
    viewToShare.layer.cornerRadius = 6.0;
    viewToShare.layer.masksToBounds = YES;

    UIView *testViewCopy = [[UIView alloc]init];
    testViewCopy.backgroundColor = [UIColor clearColor];
    testViewCopy.contentMode = UIViewContentModeScaleAspectFit;
    testViewCopy.layer.masksToBounds = YES;
    testViewCopy.tag = 0;

    UITextView *textViewCopy = [[UITextView alloc]init];
    textViewCopy.backgroundColor = [UIColor clearColor];
    textViewCopy.tag = 1;
    textViewCopy.textContainerInset = self.textView.textContainerInset;

    UIImageView *profileImageViewCopy = [[UIImageView alloc]initWithFrame:CGRectMake(2, 2, 32, 32)];
    profileImageViewCopy.contentMode = UIViewContentModeScaleAspectFit;
    profileImageViewCopy.layer.masksToBounds = YES;
    profileImageViewCopy.image = [self profileImage];
    profileImageViewCopy.tag = 2;
    profileImageViewCopy.layer.cornerRadius = profileImageViewCopy.frame.size.width / 2.0;

    viewToShare.frame = CGRectMake(0, 0, size.width, size.height);
    testViewCopy.frame = CGRectMake(0, 0, size.width, size.width);
    textViewCopy.frame = CGRectMake(0, 0, size.width, size.height);

    NSAttributedString *attributedStringCopy = [[NSAttributedString alloc]initWithAttributedString:self.textView.attributedText];

    textViewCopy.attributedText = attributedStringCopy;

    [viewToShare addSubview:testViewCopy];
    [viewToShare addSubview:textViewCopy];
    [viewToShare addSubview:profileImageViewCopy];

    return viewToShare;
}

- (NSData *)getSnapshotDataFromView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *snapShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return UIImagePNGRepresentation(snapShot);
}

1 个答案:

答案 0 :(得分:6)

您的代码表现正常。所有兄弟视图 - 一个共同的超级视图的子视图 - 具有明确的分层顺序,从前到后。 addSubview:将子视图添加为其兄弟姐妹中的 last ;因此,它在同一超视图的所有现有子视图的前面分层。如果这不是您想要的,请将子视图从前面插入另一层,或者添加它(在前面),然后以分层顺序将其向后移动。

此外(在这里我认为我们越来越接近你注意到的特殊现象),视图本身就是层次。因此,视图的分层顺序实际上是层的分层顺序的子集。我刚才所说的关于视图的事情同样适用于层,因为视图层:如果你将一个子层添加到一个超级层,它会被添加到该超层的所有其他子层之前,如果该超级层实际上是一个视图,则包括任何子视图

正如我在当前版本的书中所写:

  

视图的子视图底层是该视图底层的子层,就像该视图底层的任何其他子层一样。因此,它可以按照绘制顺序定位在它们之间的任何位置。对于初学者来说,视图可以穿插在其superview底层的子层中这一事实令人惊讶。

enter image description here

听起来你刚刚发现了这一点,并且感到非常惊讶。

在活动术语中,根据渲染树的绘制可能会有所帮助。换句话说,不要考虑事物看起来的方式,而要考虑iOS 做什么。除了最终超层之外,层可以具有超层,并且除了超层的第一子层之外,层可以具有先前的兄弟。相反,一个层可以有子层,它可以有下一个兄弟。我们首先绘制终极超级层(窗口)。然后,对于我们刚刚绘制的每个图层,按顺序遵循以下两个规则:

  • 绘制第一个子图层(如果有)。

  • 绘制下一个兄弟,如果有的话。

每次我们绘制一个图层时,它都在我们之前绘制的所有的前面。因此,超级层的所有子层都出现在超级层的前面,并且所有后来的兄弟姐妹(及其子层)出现在所有先前的兄弟姐妹(及其子层)的前面。这会导致您在屏幕上看到的内容。

(但请注意,您有更大的灵活性,因为在兄弟姐妹中,您可以通过设置图层的zPosition属性来操纵绘图顺序而无需重新排列兄弟姐妹。)