How Is the Relation Between Uiview's Clipstobounds and Calayer's Maskstobounds

masksToBounds vs. clipsToBounds

masksToBounds

Any sublayers of the layer that extend outside its boundaries will be clipped to those boundaries. Think of the layer, in that case, as a window onto its sublayers; anything outside the edges of the window will not be visible. When masksToBounds is NO, no clipping occurs.

When the value of this property is true, Core Animation creates an implicit clipping mask that matches the bounds of the layer and includes any corner radius effects. If a value for the mask property is also specified, the two masks are multiplied to get the final mask value.

you can get the more information in API Reference.

clipToBounds

The use case for clipsToBounds is more for subviews which are partially outside the main view. For example, I have a (circular) subview on the edge of its parent (rectangular) UIView. If you set clipsToBounds to YES, only half the circle/subview will be shown. If set to NO, the whole circle will show up. Just encountered this so wanted to share

for more information sample link

Why masksToBounds = YES prevents CALayer shadow?

Because shadow is an effect done outside the View, and that masksToBounds set to YES will tell the UIView not to draw anything that is outside itself.

If you want a roundedCorner view with shadow I suggest you do it with 2 views:

UIView *view1 = [[UIView alloc] init];
UIView *view2 = [[UIView alloc] init];

view1.layer.cornerRadius = 5.0;
view1.layer.masksToBounds = YES;
view2.layer.cornerRadius = 5.0;
view2.layer.shadowColor = [[UIColor blackColor] CGColor];
view2.layer.shadowOpacity = 1.0;
view2.layer.shadowRadius = 10.0;
view2.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
[view2 addSubview:view1];
[view1 release];

What UIView layer.masksToBounds is doing if set to YES?

If the masksToBounds property is set to YES, any sublayers of the layer that extend outside its boundaries will be clipped to those boundaries. Think of the layer, in that case, as a window onto its sublayers; anything outside the edges of the window will not be visible. When masksToBounds is NO, no clipping occurs, and any sublayers that extend outside the layer's boundaries will be visible in their entirety (as long as they don't go outside the edges of any superlayer that does have masking enabled).

what is relation between masksToBounds and cornerRadius?

After providing cornerRadius which specifies a radius used to draw the rounded corners of the receiver’s background.

Now it depends on masksToBounds which determines if the sublayers are clipped to the receiver’s bounds. So if it is set to YES, an implicit mask matching the layer bounds is applied to the layer, including the effects of the cornerRadius property. If it is set to YES and a mask property is specified, the two masks are multiplied to get the actual mask values.

For example:

If you set that on a CALayer with image contents, the image will still be drawn outside the corner radius boundary. You can solve this by setting sublayer.masksToBounds to YES; but if you do that, the shadows won’t show up because they’ll be masked out!

CALayer content goes out of bounds - iOS

You should put the layer you are scaling inside of another layer and mask that one instead (the superlayer). The same thing works with views.

I.e. You have two views / layers: clippingView and scalingView where scalingView is the subview of clippingView and clippingView is the view that actually clips to it's bounds.

[clippingView addSubview:scalingView];
clippingView.clipsToBounds = YES;

or using layers

[clippingLayer addSublayer:scalingLayer];
clippingLayer.masksToBounds = YES;

Not all pixels clipped when using UIView.layer.clipsToBounds = true in conjunction with CABasicAnimation

I copy your code into the project and I can reproduce this issue. But if you add the animation to another CALayer, that seems to resolve the issue.

extension UIView {

static var kRotationAnimationKey: String {
return "kRotationAnimationKey"
}

func makeAnimationLayer() -> CALayer {

let results: [CALayer]? = layer.sublayers?.filter({ $0.name ?? "" == "animationLayer" })

let animLayer: CALayer
if let sublayers = results, sublayers.count > 0 {
animLayer = sublayers[0]
}
else {
animLayer = CAShapeLayer()
animLayer.name = "animationLayer"
animLayer.frame = self.bounds
animLayer.contents = UIImage(named: "imageNam")?.cgImage
layer.addSublayer(animLayer)
}

return animLayer
}

func rotate(duration: Double = 1, startPoint: CGFloat) {
if layer.animation(forKey: UIView.kRotationAnimationKey) == nil {

let animLayer = makeAnimationLayer()

let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = startPoint
rotationAnimation.toValue = (CGFloat.pi * 2.0) + startPoint
rotationAnimation.duration = duration
rotationAnimation.repeatCount = Float.infinity
animLayer.add(rotationAnimation, forKey: UIView.kRotationAnimationKey)
}
}

func stopRotating(beginTime: Double!, startingAngle: CGFloat) -> CGFloat? {

let animLayer = makeAnimationLayer()

if animLayer.animation(forKey: UIView.kRotationAnimationKey) != nil {
let animation = animLayer.animation(forKey: UIView.kRotationAnimationKey)!
let elapsedTime = CACurrentMediaTime() - beginTime
let angle = elapsedTime.truncatingRemainder(dividingBy: animation.duration)/animation.duration
animLayer.transform = CATransform3DMakeRotation(CGFloat(angle) * (2 * CGFloat.pi) + startingAngle, 0.0, 0.0, 1.0)
animLayer.removeAnimation(forKey: UIView.kRotationAnimationKey)
return (CGFloat(angle) * (2 * CGFloat.pi)) + startingAngle
}
else {
return nil
}
}

How to correctly set a circle imageView with Swift?

clipsToBounds is a boolean value that determines whether subviews are confined to the bounds of the view.
Setting this value to YES causes subviews to be clipped to the bounds of the receiver. If set to NO, subviews whose frames extend beyond the visible bounds of the receiver are not clipped. The default value is NO.
Basically, this thing plays with the view's property.

Whereas masksToBounds is a boolean indicating whether sublayers are clipped to the layer’s bounds.And this thing plays with the layer of the view.

what is the relationship between a UIView.frame and CALayer.frame? (both pre and post a CATransform3D)

If you are working with Core Animation and layers, you should focus on the following CALayer properties:

  1. position
  2. bounds
  3. anchorPoint
  4. transform

A quote from Apple Technical Q&A QA1620 available here:

Q: When I try to animate the frame of a CALayer nothing happens. Why?

A: The frame property of a CALayer is a derived property, dependent on
the position, anchorPoint, bounds and transform of the layer. Instead
of animating the frame, you should instead animate the position or
bounds, depending on what effect you are trying to accomplish.



Related Topics



Leave a reply



Submit