Problem
I have a custom UIView that has an image and selection (border) subview. I want to be able to add this custom UIView as a subview of a larger blank view. Here’s the catch, the larger blank view needs to clip all of the subviews to its bounds (clipToBounds
). However, the user can select one of the custom UIViews within the large blank view, where the subview is then highlighted by a border.
The problem is that because the large blank view clips to bounds, the outline for the selected subview is cut off.
I want the image in the subview to clip to the bounds of the large blank view, but still be able to see the full selection outline of the subview (which is cut off due to the large blank view’s corner radius.
I am using UIKit and Swift
The image part of the subview clips to the bounds (corner radius) of the large blank view, but the outline selection view in the subview should not.
Thanks in advance for all your help!
3
Answers
This is a pretty common problem which may have multiple solutions. In the end though I always find it best to simply go one level higher:
You would put all your current views on
ContentView
. Then introduce another view which represents your selection and put it on the same level as yourContentView
.In the end this will give you most flexibility. It can still get a bit more complicated when you add things like shadows. But again "more views" is usually the end solution.
I think what you are looking for is not technically possible as defined by the docs
From the docs:
clipsToBounds
Setting this value to true causes subviews to be clipped to the bounds of the receiver. If set to false, subviews whose frames extend beyond the visible bounds of the receiver are not clipped. The default value is false.
So the subviews do not have control of whether they get clipped or not, it’s the container view that decides.
So I believe Matic’s answer is right in that the structure he proposes gives you the most flexibility.
With that being said, here are a couple of work arounds I can think of:
First, set up to recreated your scenario
Custom UIView
Then in the view controller
This gives me your current experience
Work Around 1. – Shrink subviews on selection
When the view is not selected, everything looks fine. When the view is selected, you could reduce the width and height of the custom subview with some animation while adding the border.
Work Around 2. – Manually clip desired subviews
You go through each subview in your container view and:
To do that, I created a custom UIView subclass for the container view
Then make sure to adjust the following lines where you create your views:
This gives me your desired output
You’ll likely run into a lot of problems trying to get a subview’s border to display outside its superView’s clipping bounds.
One approach is to add an "Outline View" as a sibling of the "Clipping View":
When you select a clippingView’s subview – and drag it around – set the frame of the outlineView to match the frame of that subview.
You’ll want to set
.isUserInteractionEnabled = false
on the outlineView so it doesn’t interfere with touches on the subviews.