Mask overlay on UIScrollView - iphone

how would you go about overlaying a mask image of sorts on top of a UIScrollView?
For example, I have an image with black on the left and right fading to white in the center. I'd like to use this so that the items in my scroll view gradually fade out to the sides and the center item is completely opaque.
Also, the background of the view the scrollview is placed on is an image (not a solid color) which is dynamic and can change.
Any ideas?

Your question wound up being the best source I could find on the basic problem, so I decided to post my solution here.
If you add the mask directly to the scroll view, you wind up applying the mask to the content itself for some reason -- i. e. the transparency doesn't shift as you scroll. As per the suggestions of other posts, I put the gradient in a view over (or rather, containing) the scroll view. As a result, scrollContainer is a UIViewObject whose sole subview is the scroll view in question.
This mask is configured for left-to-right scrolling. You could change it to top to bottom by manipulating the start and end point properties of the gradient.
The one down side is that this also clips the scroll position bar indicator of the scroll view. Since my scenario doesn't need one, that's acceptable, but your mileage may vary.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = scrollView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithWhite:0 alpha:0] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:0] CGColor], nil];
gradient.locations=[NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:.1],
[NSNumber numberWithFloat:.9],
[NSNumber numberWithFloat:1], nil];
gradient.startPoint=CGPointMake(0, .5);
gradient.endPoint=CGPointMake(1, .5);
[scrollContainer.layer setMask:gradient];

If you have a solid color background behind the scrollview, you'll get better performance by just overlaying an image on top of the scroll view rather than trying to perform a mask within it.

Try something along these lines:
// I assume you are in a UIViewController and self.view is set to some kind of view
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview: scrollView];
[scrollView release];
// add img with gradient
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"my-gradient.png"];
imgView.frame = CGRectMake(0, 0, 160, 420);
[self.view addSubview: imgView];
[imgView release];
This would give you a gradient that begins on the left and goes all the way to the center for the entire height, assuming that "my-gradient.png" is an image that actually contains a gradient.

These kind of manipulations are big ressources consumers. The best approach would be (if your case allows it) to put a mask image OVER your UIScrollView. This image's background shoud be transparent (ex. png32) and the image should be an alpha-gradient.

Use insertView:yourView atIndex:0

Related

Adding Gradient Hides UILabel Text In UITableViewCell

I am trying to add gradient layer behind the UILabel's text which resides in a custom UITableViewCell. Problem is that gradient is hiding my label's text. I have already visited this link, but it is not working for me.So how can I add it behind the text layer?
What I have done so far is:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, 0, buyPrice_port.frame.size.width, buyPrice_port.frame.size.height);
gradient.colors = [NSArray arrayWithObjects:(id)gainBackgroundColor1, (id)gainBackgroundColor2, nil];
gradient.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0.00], [NSNumber numberWithFloat:0.70] , nil];
[buyPrice_port.layer insertSublayer:gradient atIndex:0];
buyPrice_port.textColor = [UIColor blackColor];
You can simply add a view behind the UILabel (i.e. add the label as a subview of the gradient view) and keep the label transparent.

UIView with glass effect

I want to create a view which should have a glass like effect. It should look shining as well.
On that i want to add a UITextView which should appear transparent. I'm new to IPhone and not getting how to do this.
I don't want to add image. Wanna do programmatically. The view should look like as if it is a mobile screen.
Thanks
You'll have to do things if you don't want to use the image.
Add one UIView Use this code. And set gradient background color to it. Which will give you shiny glass like effect.
Here is the code:
.h file :
UIColor *pinkDarkOp;
UIColor *pinkLightOp;
CAGradientLayer *gradient;
.m file :
img_TopBarView = [[UIView alloc]initWithFrame:CGRectMake(0.0,0.0,1024.0,50.0)];
img_TopBarView.userInteractionEnabled = YES;
pinkDarkOp = [UIColor colorWithRed:15.0f/255.0 green:138.0f/255.0 blue:216.0f/255.0 alpha:1.0];
pinkLightOp = [UIColor colorWithRed:12.0f/255.0 green:91.0f/255.0 blue:183.0f/255.0 alpha:1.0];
gradient = [CAGradientLayer layer];
gradient.frame = [[img_TopBarView layer] bounds];
gradient.colors = [NSArray arrayWithObjects:(id)pinkDarkOp.CGColor,(id)pinkLightOp.CGColor,nil];
gradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f],[NSNumber numberWithFloat:0.7],nil];
[[img_TopBarView layer] insertSublayer:gradient atIndex:0];
[self.view addSubview:img_TopBarView];
[img_TopBarView release];
You have to take the values of pinkDarkOp and pinkLightOp as per your need. You can get this color code anywhere on google.
For eg : http://gradients.glrzad.com
For Creating the transparent UITextView you can use the alpha property of the UITextView.
I hope this helps.

How to create a UIView that contains 0 to 1 opacity value (alpha value) from bottom to top?

I want to create a UIView that contains gradually increasing opacity value in it. That is, the UIView's bottom will start with 0.0 as its alpha value and it should end with 1.0 at the top of the UIView. Is it possible to make such view? Or should i separate that view and give them the various alpha value?
Thanks in Advance
For future reference, the term for that sort of effect is a gradient.
You can make a view with a gradient image behind it:
Create a UIImageView behind the UIView you want to set a gradient on
Set the UIView's background color to clear.
Set the background image of the UIImageView to a gradient PNG you have created.
The gradient PNG can be 1px wide and say 64px high (or higher, depending on how smooth you want the gradient to look). Make it in a paint program (GIMP is a decent one).
A way to do it purely in code is using CAGradientLayer:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithWhite: 0.0 alpha:0.0] CGColor],
(id)[[UIColor colorWithWhite: 0.0 alpha:1.0] CGColor], nil];
gradient.startPoint = CGPointMake(0.5, 0.0); // default; bottom of the view
gradient.endPoint = CGPointMake(0.5, 1.0); // default; top of the view
[self.view.layer insertSublayer:gradient atIndex:0];

Simultaneous animation when entering editing mode of UITableViewCell

when entering the editing mode in a UITableViewCell through setEditing:animated:, there is an (implicit) animation where the cells move right and the delete "buttons" appear at the left.
How do I manage, probably with Core Animation features, to run a second animation simultaneously to the first animation when entering editing mode, i.e. with the the same starting time, duration, timing curve, and so on? (I'm actually trying to change the width of a cell's sublayer synchronously.)
I studied the Core Animation Programming Guide and tried some of the techniques in a custom UITableViewCell class, for example by overriding willTransitionToState:. In principle, everything works well, however, I can only manage to have the animations one after the other, but not simultaneously.
Any advice is greatly appreciated.
Alright, it's much simpler than I initially thought. The behavior I sought can rather easily be achieved by correctly initializing the layers (or views) in the custom UITableViewCell. However, I realized that the order and, e.g., whether you manipulate bounds or frame properties is quite important.
The following code snippet does the job for a cell in a grouped UITableView. In this example, a CAGradientLayer (as an example for a CALayer) is added as a sublayer to a UIView, which itself is added as a subview to self.contentView of the cell. The subview's frame is tweaked to fit into the contentView. The code goes, e.g., into initWithStyle:reuseIdentifier: of a custom UITableViewCell:
CGRect realFrame = self.contentView.frame;
realFrame.size.width += 20;
UIView *gradientView = [[UIView alloc] initWithFrame:realFrame];
CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
gradientLayer.anchorPoint = CGPointMake(0.0, 0.0);
gradientLayer.frame = gradientView.frame;
gradientLayer.position = CGPointMake(0.0, 0.0);
[gradientLayer setColors:[NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0] CGColor], (id)[[UIColor clearColor] CGColor], nil]];
gradientLayer.startPoint = CGPointMake(0.5, 0.0);
gradientLayer.endPoint = CGPointMake(0.5, 1.0);
gradientView.layer.masksToBounds = YES;
gradientView.layer.cornerRadius = 8.0;
[gradientView.layer insertSublayer:gradientLayer atIndex:0];
[self.contentView addSubview:gradientView];
gradientView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[gradientView release];
[gradientLayer release];

Gradients on UIView and UILabels On iPhone [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Manually drawing a gradient in iPhone apps?
My application needs to display text in either a UIView or UILabel but the back ground must be a gradient as opposed to a true UIColor. Using a graphics program to create desired look is no good as the text may vary depending on data returned from a server.
Does anyone know the quickest way to tackle this?
Your thoughts are greatly appreciated.
I realize this is an older thread, but for future reference:
As of iPhone SDK 3.0, custom gradients can be implemented very easily, without subclassing or images, by using the new CAGradientLayer:
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)] autorelease];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[view.layer insertSublayer:gradient atIndex:0];
Take a look at the CAGradientLayer docs. You can optionally specify start and end points (in case you don't want a linear gradient that goes straight from the top to the bottom), or even specific locations that map to each of the colors.
You can use Core Graphics to draw the gradient, as pointed to in Mike's response. As a more detailed example, you could create a UIView subclass to use as a background for your UILabel. In that UIView subclass, override the drawRect: method and insert code similar to the following:
- (void)drawRect:(CGRect)rect
{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35, // Start color
1.0, 1.0, 1.0, 0.06 }; // End color
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
CGRect currentBounds = self.bounds;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));
CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
}
This particular example creates a white, glossy-style gradient that is drawn from the top of the UIView to its vertical center. You can set the UIView's backgroundColor to whatever you like and this gloss will be drawn on top of that color. You can also draw a radial gradient using the CGContextDrawRadialGradient function.
You just need to size this UIView appropriately and add your UILabel as a subview of it to get the effect you desire.
EDIT (4/23/2009): Per St3fan's suggestion, I have replaced the view's frame with its bounds in the code. This corrects for the case when the view's origin is not (0,0).
Note: The results below apply to older versions of iOS, but when testing on iOS 13 the stepping doesn't occur. I don't know for which version of iOS the stepping was removed.
When using CAGradientLayer, as opposed to CGGradient, the gradient is not smooth, but has noticeable stepping to it. See :
To get more attractive results it is better to use CGGradient.
You could also use a graphic image one pixel wide as the gradient, and set the view property to expand the graphic to fill the view (assuming you are thinking of a simple linear gradient and not some kind of radial graphic).
Mirko Froehlich's answer worked for me, except when i wanted to use custom colors. The trick is to specify UI color with Hue, saturation and brightness instead of RGB.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = myView.bounds;
UIColor *startColour = [UIColor colorWithHue:.580555 saturation:0.31 brightness:0.90 alpha:1.0];
UIColor *endColour = [UIColor colorWithHue:.58333 saturation:0.50 brightness:0.62 alpha:1.0];
gradient.colors = [NSArray arrayWithObjects:(id)[startColour CGColor], (id)[endColour CGColor], nil];
[myView.layer insertSublayer:gradient atIndex:0];
To get the Hue, Saturation and Brightness of a color, use the in built xcode color picker and go to the HSB tab. Hue is measured in degrees in this view, so divide the value by 360 to get the value you will want to enter in code.
This is what I got working- set UIButton in xCode's IB to transparent/clear, and no bg image.
UIColor *pinkDarkOp = [UIColor colorWithRed:0.9f green:0.53f blue:0.69f alpha:1.0];
UIColor *pinkLightOp = [UIColor colorWithRed:0.79f green:0.45f blue:0.57f alpha:1.0];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = [[shareWordButton layer] bounds];
gradient.cornerRadius = 7;
gradient.colors = [NSArray arrayWithObjects:
(id)pinkDarkOp.CGColor,
(id)pinkLightOp.CGColor,
nil];
gradient.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.7],
nil];
[[recordButton layer] insertSublayer:gradient atIndex:0];
I achieve this in a view with a subview that is an UIImageView. The image the ImageView is pointing to is a gradient. Then I set a background color in the UIView, and I have a colored gradient view. Next I use the view as I need to and everything I draw will be under this gradient view. By adding a second view on top of the ImageView, you can have some options whether your drawing will be below or above the gradient...