子视图的子图层重叠较高的子视图
我有一个问题:我正在创建一个从方法返回的UIView
,那部分很好,但我注意到的是,当我将子图层添加到其中一个子视图时,这些图层会重叠更高的子视图在层次结构( testViewCopy
)中,添加到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); }
您的代码表现正常。 所有兄弟视图 – 一个共同的超级视图的子视图 – 具有明确的分层顺序,从前到后。 addSubview:
将子视图添加为其兄弟姐妹中的最后一个 ; 因此,它在同一超视图的所有现有子视图的前面分层。 如果这不是您想要的,请将子视图从前面插入另一层,或者添加它(在前面),然后按层次顺序将其向后移动。
而且(在这里我认为我们越来越接近你注意到的特殊现象),视图本身就是层次。 因此,视图的分层顺序实际上是层的分层顺序的子集。 我刚才所说的关于视图的事情同样适用于图层,因为视图是图层:如果你向超级图层添加一个子图层,它会被添加到该超级图层的所有其他子图层前面, 包括任何子视图,如果该超级图层实际上是视图。
正如我在当前版本的书中所写:
视图的子视图的底层是该视图的底层图层的子图层,就像该视图的底层图层的任何其他子图层一样。 因此,它可以按照绘制顺序定位在它们之间的任何位置。 对于初学者来说,视图可以穿插在其superview底层的子层中这一事实令人惊讶。
听起来你刚刚发现了这一点,并且感到非常惊讶。
从活动的角度来看,渲染树的绘制可能会有所帮助。 换句话说,不要考虑事物的外观 ,而要考虑iOS的function 。 除了最终的超级层之外,层可以具有超级层,并且除了超级层的第一子层之外,层可以具有先前的兄弟级。 相反,一个层可以有子层,它可以有下一个兄弟。 我们首先绘制终极超级层(窗口)。 然后,对于我们刚刚绘制的每个图层,按顺序遵循以下两个规则:
-
绘制其第一个子层(如果有)。
-
画下一个兄弟,如果有的话。
每次我们绘制一个图层时,它都在我们之前绘制的所有内容之前。 因此,超级层的所有子层都出现在超级层的前面,并且所有后来的兄弟姐妹(及其子层)出现在所有先前的兄弟姐妹(及其子层)的前面。 这会导致您在屏幕上看到的内容。
(但请注意,您具有更大的灵活性,因为在兄弟姐妹中,您可以通过设置图层的zPosition
属性来操纵绘图顺序而无需重新排列兄弟姐妹。)