iOS核心animation:CALayer bringSublayerToFront?
如何将CALayer sublayer
带到所有子图层的前面,类似于-[UIView bringSubviewToFront]
?
这是@ MattDiPasquale实现的变体,它更精确地反映了UIView的逻辑:
- (void) bringSublayerToFront:(CALayer *)layer { [layer removeFromSuperlayer]; [self insertSublayer:layer atIndex:[self.sublayers count]]; } - (void) sendSublayerToBack:(CALayer *)layer { [layer removeFromSuperlayer]; [self insertSublayer:layer atIndex:0]; }
注意 :如果你不使用ARC,你可能希望在两个函数的顶部添加[layer retain]
并且在两个函数的底部添加[layer retain]
[layer release]
,以确保在保留count = 1的情况下layer
不会被意外地破坏。
我很好奇为什么这些答案都没有提到CALayer上的zPosition属性。 核心animation看这个属性来找出层的渲染顺序。 值越高,越靠前。 只要你的zPosition是0,这些答案都可以工作,但是为了方便地把一个图层放在前面,设置它的zPosition值比所有其他子图层更高。
这里有正确的代码
- (void)bringSublayerToFront:(CALayer *)layer { CALayer *superlayer = layer.superlayer; [layer removeFromSuperlayer]; [superlayer insertSublayer:layer atIndex:[superlayer.sublayers count]]; } - (void)sendSublayerToBack:(CALayer *)layer { CALayer *superlayer = layer.superlayer; [layer removeFromSuperlayer]; [superlayer insertSublayer:layer atIndex:0]; }
这是正确的代码:
-(void)bringSubLayerToFront:(CALayer*)layer { [layer.superLayer addSubLayer:layer]; } -(void)sendSubLayerToBack:(CALayer*)layer { [layer.superlayer insertSublayer:layer atIndex:0]; }
您可以在CALayer的类别中实现此function,如下所示:
CALayer的+ Extension.h
#import <QuartzCore/QuartzCore.h> typedef void (^ActionsBlock)(void); @interface CALayer (Extension) + (void)performWithoutAnimation:(ActionsBlock)actionsWithoutAnimation; - (void)bringSublayerToFront:(CALayer *)layer; @end
CALayer的+ Extension.m
#import "CALayer+Extension.h" @implementation CALayer (Extension) + (void)performWithoutAnimation:(ActionsBlock)actionsWithoutAnimation { if (actionsWithoutAnimation) { // Wrap actions in a transaction block to avoid implicit animations. [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; actionsWithoutAnimation(); [CATransaction commit]; } } - (void)bringSublayerToFront:(CALayer *)layer { // Bring to front only if already in this layer's hierarchy. if ([layer superlayer] == self) { [CALayer performWithoutAnimation:^{ // Add 'layer' to the end of the receiver's sublayers array. // If 'layer' already has a superlayer, it will be removed before being added. [self addSublayer:layer]; }]; } } @end
为了方便访问,您可以在项目的Prefix.pch (预编译头文件)中#import "CALayer+Extension.h"
。
像这样创build一个CALayer的类别:
@interface CALayer (Utils) - (void)bringSublayerToFront; @end @implementation CALayer (Utils) - (void)bringSublayerToFront { CGFloat maxZPosition = 0; // The higher the value, the closer it is to the front. By default is 0. for (CALayer *layer in self.superlayer.sublayers) { maxZPosition = (layer.zPosition > maxZPosition) ? layer.zPosition : maxZPosition; } self.zPosition = maxZPosition + 1; } @end
Swift 4版本。
想法层本身有bringToFront
和sendToBack
方法。
#if os(iOS) import UIKit #elseif os(OSX) import AppKit #endif extension CALayer { func bringToFront() { guard let sLayer = superlayer else { return } removeFromSuperlayer() sLayer.insertSublayer(self, at: UInt32(sLayer.sublayers?.count ?? 0)) } func sendToBack() { guard let sLayer = superlayer else { return } removeFromSuperlayer() sLayer.insertSublayer(self, at: 0) } }
用法:
let view = NSView(frame: ...) view.wantsLayer = true view.layer?.backgroundColor = NSColor.gray.cgColor let l1 = CALayer(...) let l2 = CALayer(...) view.layer?.addSublayer(l1) view.layer?.addSublayer(l2) l1.bringToFront()
我不认为这样的方法存在,但很容易推出自己的方法。
// CALayer+Additions.h @interface CALayer (Additions) - (void)bringSublayerToFront:(CALayer *)layer; - (void)sendSublayerToBack:(CALayer *)layer; @end // CALayer+Additions.m @implementation CALayer (Additions) - (void)bringSublayerToFront:(CALayer *)layer { CALayer *superlayer = self.superlayer; [self removeFromSuperlayer]; [superlayer insertSublayer:gradientLayer atIndex:[self.sublayers count]-1]; } - (void)sendSublayerToBack:(CALayer *)layer { CALayer *superlayer = self.superlayer; [self removeFromSuperlayer]; [superlayer insertSublayer:gradientLayer atIndex:0]; }
- UIImageViewcaching图像?
- 如何将UIView的右上angular90度旋转/旋转?
- 在Swift 3中有多个CGAffineTransforms
- 我可以animation的UIScrollView contentOffset属性通过它的图层?
- 将自动布局与核心animation结合在一起
- 在UIView中绘制三angular形切口以供select指示
- 有没有办法在UIViewPropertyAnimator中观察对fractionComplete的更改
- 在animation边界上更改animationCAShapeLayerpath
- 如何用定时器重复调用一个方法(重新加载…)来为一个转换设置animation