Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying CAGradient mask layer to UITextView

I've got a UITextView, with scrollable text. I'm trying to apply a gradient layer to it, so the bottom of the visible text is always slightly faded out.

Here's my code:

CAGradientLayer *maskLayer = [CAGradientLayer layer];

maskLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor], (id)[[UIColor yellowColor] CGColor], nil];
maskLayer.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
                       [NSNumber numberWithFloat:0.2],
                       [NSNumber numberWithFloat:0.8],
                       [NSNumber numberWithFloat:1.0], nil];
maskLayer.bounds = clueTextView.bounds;
myUITextView.layer.mask = maskLayer;

Right now, this is causing the UITextViewLayer to be completely transparant - I see the background color of the UIView that the UITextViewLayer is as subview of. I can't see any of the text contained within, although I can select and copy the text to paste in to the notes program.

Any ideas what I'm missing?

like image 365
Mike Stein Avatar asked Dec 15 '22 18:12

Mike Stein


1 Answers

You have several problems.

The gradient layer's colors property needs to have the same count as its locations property. You are providing 4 locations but only 2 colors.

You are setting the gradient layer's bounds based on clueTextView but you are setting it as the mask of myUITextView.

You are setting the bounds of the gradient layer, but not its position. The default position is 0,0, meaning that the center of the gradient layer is at the upper-left corner of myUITextView. It is simpler to just set the frame of the gradient layer to the bounds of the text view.

If you fix all of these problems, you might get the effect you're looking for.

- (void)initTextViewMask {
    CAGradientLayer *maskLayer = [CAGradientLayer layer];
    maskLayer.colors = @[
        (id)[UIColor whiteColor].CGColor,
        (id)[UIColor whiteColor].CGColor,
        (id)[UIColor clearColor].CGColor];
    maskLayer.locations = @[ @0.0f, @0.8f, @1.0f ];
    maskLayer.frame = textView_.bounds;
    textView_.layer.mask = maskLayer;
}

However, you may discover new problems.

If the user can scroll the text view, you will discover that the gradient moves with the text view, which is probably not what you want. The easiest way to fix this is to embed the text view inside a container UIView, and set the mask on the container view.

If the text view can change size (perhaps due to device rotation), the mask will not automatically change size with it. You need to update the mask's frame, in layoutSubviews or viewDidLayoutSubviews.

like image 78
rob mayoff Avatar answered Dec 31 '22 02:12

rob mayoff