I have a UIScrollView that contains other subviews that are partially drawn outside of the scrollview. These views extend vertically above the scrollview. Is it possible to only allow the subviews to be drawn outside the top of the scrollview, and not allow them drawn outside of the left and right sides of the scrollview?
What is happening, is that when I manually scroll left and right, the subviews are being drawn outside of the scrollview because of the content size. Once the subview's are scroll outside of the scrollview's frame, I want to clip the subviews.
Any suggestions or is this possible?
I've managed to achieve this effect by using the layer
's mask
property and a CALayer. The following snippet clips only views from the top and the left side of a view:
let maskLayer = CALayer()
maskLayer.backgroundColor = UIColor.black.cgColor
maskLayer.frame = CGRect(x: 0, y: 0, width: 2000, height: 2000)
aView.layer.mask = maskLayer
Note that I'm using the arbitrary number 2000
as the far right and lower bounds for clipping, so you'll need to adjust the number depending on how far you want your other views to clip.
You can't specify individual sides you'd like to clip, but you could basically fake this by placing a new UIView
alongside the edge you wanted to clip (and so effectively clipping it). Alternatively you could think about ways to change your view hierarchy so that you don't have to clip subviews at all (perhaps by adjusting the scroll view's bounds and layout in some way).
It's common to do this on table or collection views for example:
/*
This is a UICollectionView, which clips normally on the left and right,
but allows some extra space horizontally.
A typical example is you need to clip the scrolling items but you
still need to allow shadows.
*/
import Foundation
import UIKit
class CustomClipCollectionView: UICollectionView {
private lazy var extraSpaceOnBaseButStillClipSidesNormally: CALayer = {
let l = CALayer()
l.backgroundColor = UIColor.black.cgColor
return l
}()
override func layoutSubviews() {
extraSpaceOnBaseButStillClipSidesNormally.frame = bounds.insetBy(
dx: 0, dy: -10)
layer.mask = extraSpaceOnBaseButStillClipSidesNormally
super.layoutSubviews()
}
}
Note! You turn off the normal "clip to bounds" feature, when using this. The ".mask" system for clipping is different and separate from the "clip to bounds" system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With