UIView 的图层蒙版动画设置框
UIView's layer mask animates setting frame
我想创建一个 UIView 子类来屏蔽自身,以便我添加到它的任何子视图都被一个圆圈裁剪。我希望在 IB 中定义此视图及其子视图,以便我可以轻松地为子视图定义布局约束。到目前为止,我有以下...
@interface BubbleView ()
// eg: this is an example of a child view that would be "under" a mask
@property(weak,nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation BubbleView
// not really sure if this kind of init is the right pattern, but it seems to work and
// I don't think this is my current problem??
+ (instancetype)bubbleViewFromNib {
BubbleView *view = [[NSBundle mainBundle] loadNibNamed:@"BubbleView" owner:nil options:nil][0];
UIImage *_maskingImage = [UIImage imageNamed:@"circlemask"];
CALayer *maskingLayer = [CALayer layer];
[view.layer addSublayer:maskingLayer];
maskingLayer.contents = (__bridge id _Nullable)(_maskingImage.CGImage);
view.layer.mask = maskingLayer;
return view;
}
- (void)layoutSubviews {
self.layer.mask.frame = self.bounds;
}
(注意:我在 IB 中将视图设置为紫色,这样我可以看到发生了什么)
这几乎可以工作,但是当拥有视图控制器调整此视图大小时,就像这样...
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
BubbleView *b = (BubbleView *)[self.view viewWithTag:222];
//b.transform = CGAffineTransformScale(b.transform, 1.2, 1.2);
b.frame = CGRectInset(b.frame, -30,-30);
}
蒙版做了一些奇怪的事情:它保持小 "jumps" 到视图的左上角,然后非常快速地动画到正确的大小(大 30,30)。 为什么要动画化?
之前...
像这样的快速动画...
将 NSLog 放在 layoutSubviews 中,我注意到它被调用了两次,这很奇怪,但仍然不足以解释快速动画。
此外,当我更改变换而不是框架时,它会完美地调整大小,没有动画。但我需要同时进行框架和变换更改。
谁能告诉我哪里做错了?
设置图层的可动画 属性 时,除非该图层是 UIView 的主要图层,否则隐式动画是默认设置。此外,frame
属性 只是 bounds
和 position
属性的外观。出于这个原因,你不应该直接设置图层的 frame
;总是自己设置 bounds
和 position
。如果您不需要动画,则需要关闭这些属性的隐式动画;最简单的方法是为当前的 CATransaction(setDisableActions
到 true
)完全关闭它,但是还有更微妙和精确的方法来完成同样的事情。
我想创建一个 UIView 子类来屏蔽自身,以便我添加到它的任何子视图都被一个圆圈裁剪。我希望在 IB 中定义此视图及其子视图,以便我可以轻松地为子视图定义布局约束。到目前为止,我有以下...
@interface BubbleView ()
// eg: this is an example of a child view that would be "under" a mask
@property(weak,nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation BubbleView
// not really sure if this kind of init is the right pattern, but it seems to work and
// I don't think this is my current problem??
+ (instancetype)bubbleViewFromNib {
BubbleView *view = [[NSBundle mainBundle] loadNibNamed:@"BubbleView" owner:nil options:nil][0];
UIImage *_maskingImage = [UIImage imageNamed:@"circlemask"];
CALayer *maskingLayer = [CALayer layer];
[view.layer addSublayer:maskingLayer];
maskingLayer.contents = (__bridge id _Nullable)(_maskingImage.CGImage);
view.layer.mask = maskingLayer;
return view;
}
- (void)layoutSubviews {
self.layer.mask.frame = self.bounds;
}
(注意:我在 IB 中将视图设置为紫色,这样我可以看到发生了什么)
这几乎可以工作,但是当拥有视图控制器调整此视图大小时,就像这样...
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
BubbleView *b = (BubbleView *)[self.view viewWithTag:222];
//b.transform = CGAffineTransformScale(b.transform, 1.2, 1.2);
b.frame = CGRectInset(b.frame, -30,-30);
}
蒙版做了一些奇怪的事情:它保持小 "jumps" 到视图的左上角,然后非常快速地动画到正确的大小(大 30,30)。 为什么要动画化?
之前...
像这样的快速动画...
将 NSLog 放在 layoutSubviews 中,我注意到它被调用了两次,这很奇怪,但仍然不足以解释快速动画。
此外,当我更改变换而不是框架时,它会完美地调整大小,没有动画。但我需要同时进行框架和变换更改。
谁能告诉我哪里做错了?
设置图层的可动画 属性 时,除非该图层是 UIView 的主要图层,否则隐式动画是默认设置。此外,frame
属性 只是 bounds
和 position
属性的外观。出于这个原因,你不应该直接设置图层的 frame
;总是自己设置 bounds
和 position
。如果您不需要动画,则需要关闭这些属性的隐式动画;最简单的方法是为当前的 CATransaction(setDisableActions
到 true
)完全关闭它,但是还有更微妙和精确的方法来完成同样的事情。