How does clipsToBounds work?
If my superview is a box measuring 10 units on each side, and my subview is 20 units wide, with clipsToBounds
set to YES
, I'll only see the part of the subview that fits within the bounds of the superview. Otherwise, if clipsToBounds
is set to NO
, I'll see the entire subview, even the parts outside the superview (assuming we're still on the screen).
As a visual example, consider the following views set up on the storyboard:
This is a white UIView
, a label in the top left corner with either a simple "1" or "2" so that I can discuss these as view1
or view2
. Additionally, the black view is the same size as the white view, but it's origin is at the white view's center.
In the view controller's viewDidLoad
method, we have the following code:
Objective-C:
- (void)viewDidLoad {
[super viewDidLoad];
self.view1.clipsToBounds = YES;
self.view2.clipsToBounds = NO;
}
Swift:
override func viewDidLoad() {
super.viewDidLoad()
self.view1.clipsToBounds = true
self.view2.clipsToBounds = false
}
When we run the code and look at in the simulator or on the device, we get the following results:
So, despite these views being set up identically (except clipsToBounds
), they look different. This is what clipsToBounds
does. Setting it to YES
will provide the top result, while setting it to NO
provides the bottom result.
If we debug the view hierarchy, we can see more clearly that the black boxes both do actually extend past the boarders of the white view, but only view 2 shows this when the app is actually running:
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 does clipsToBounds prevent the subviews to be touched?
My understanding is that the hit test starts from the subview and work its way up to the superview.
Then your understanding is completely wrong. Let’s fix that. First, let's clear up some other misunderstandings:
The
reversed
is a total red herring; it has nothing to do with it. The subviews are always tested in reverse order, because a subview in front needs to take precedence over a subview behind.The
clipsToBounds
is a total red herring too. All it does is change whether you can see a subview outside its superview; it does not have any effect on whether you can touch a subview outside its superview.
Okay, so how does this work? Let's take view V which contains a subview A. Let's suppose that A is outside V. Assume you can see A, and you tap A.
Now hit-testing begins. But here's the thing: it starts at the level of the window, and works its way down the view hierarchy. So the window starts by interrogating its subviews; there is just one, the main view of the view controller.
So now we recurse, and the main view of the view controller interrogates its subviews. One of those is V. "Hey, V, was the tap inside you?" "No!" (You have to agree that that is the correct answer, because we already said that A is outside V.)
So the main view of the view controller gives up on V, and never finds out that the tap was on A, because we never recursed down that far. So it reports back up the chain: "The tap was not on any of my subviews, so I have to report that the tap was on me." The tap has fallen through to the view controller's main view.
But you can change that behaviour by overriding the implementation of hitTest
:
override func hitTest(_ point: CGPoint, with e: UIEvent?) -> UIView? {
if let result = super.hitTest(point, with:e) {
return result
}
for sub in self.subviews.reversed() {
let pt = self.convert(point, to:sub)
if let result = sub.hitTest(pt, with:e) {
return result
}
}
return nil
}
UIView clipsToBounds doesn't work
I found a solution, I move the clipsToBound in the viewDidLayoutSubviews instead viewDidLoad and now works
override func viewDidLoad() {
super.viewDidLoad()
contentView.layer.cornerRadius = Dimensions.CornerRaius
contentView.dropShadow()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
contentView.clipsToBounds = true
}
ClipsToBounds is not working in cells
You should set the clipsToBounds
property of the higher level container view (like the contentView
of your cell.)
Why does UITextView set clipsToBounds to true by default?
For a UIScrollView
, clipsToBounds
is set to true
by default. I think this so that its subviews disappear as they get scrolled beyond its bounds. I guess UITextView
just inherits this setting.
I think that's OK, but I'd suggest adding the subview to the superview of your UITextView
instead.
clipsToBounds causes UIImage to not display in iOS10 & XCode 8
I had the same problem and calling layoutIfNeeded
before all the rounded corner / clipsToBounds
stuff fixed the issue. iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds
Related Topics
Ios: What's the Fastest, Most Performant Way to Make a Screenshot Programmatically
How to Change Inside Background Color of Uisearchbar Component on iOS
Nsurlconnection Sendasynchronousrequest Can't Get Variable Out of Closure
Invalid Swift Support/Invalid Implementation of Swift
Ios9 Does Not Load Insecure Resources from a Secure Page (Ssl/Https)
Autolayout with Hidden Uiviews
Customizing the More Menu on a Tab Bar
Example of Nsattributedstring with Two Different Font Sizes
iOS 9 Facebook Login Simulator -Canopenurl: Failed for Url: "Fbauth2:///" - Error: "(Null)"
How to Initialize/Instantiate a Custom Uiview Class with a Xib File in Swift
Drop-Down List in Uitableview in iOS
How to Recognize Which Pin Was Tapped
Xcode Stuck at "Your Application Is Being Uploaded"
How to Add Minutes to Current Time in Swift
How to Use Any in Codable Type
Converting iPhone Xib to iPad Xib
How to Make Uitextview Height Dynamic According to Text Length