Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you limit UIView Clip Subviews to certain sides of a view?

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?

like image 419
Justin Moore Avatar asked Feb 09 '14 23:02

Justin Moore


3 Answers

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.

like image 141
Max Chuquimia Avatar answered Oct 22 '22 23:10

Max Chuquimia


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).

like image 36
lxt Avatar answered Oct 22 '22 22:10

lxt


Limit clip to certain sides of a view:

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.

like image 1
Fattie Avatar answered Oct 22 '22 22:10

Fattie