How can I draw a shadow on the top of a UITableViewCell? Tweetbot does this, here's a screenshot:
You could use a CAGradientLayer. In your cellForRowAtIndexPath, when creating a cell, create a gradient layer and add it to your cell. Note, you'll have to import the QuartzCore framework. Like so,
//top shadow
UIView *topShadowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 10)];
CAGradientLayer *topShadow = [CAGradientLayer layer];
topShadow.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, 10);
topShadow.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.25f] CGColor], (id)[[UIColor clearColor] CGColor], nil];
[topShadowView.layer insertSublayer:topShadow atIndex:0];
[cell.contentView addSubview:topShadowView];
Related
I have a horizontal-scrolling UICollectionView within the main view of a view controller like so (Grey is UIView, Wood is UICollectionView):
I want to add fixed faded gradients on the far left & far right sies of this UICollectionView so that the scrolls appear to vanish as the user scrolls. How would I go about doing this? Does it involve some use of CAGradientLayer? I would be grateful for any help you can give me!
I actually managed to figure this out using one mask layer thanks to this tutorial at cocoanetics. Here's what I did:
#interface ScalesViewController : UIViewController
{
CAGradientLayer *maskLayer;
}
#end
Then in the .m, I placed in the following:
- (void)viewDidAppear:(BOOL)animated
{
[super viewWillAppear: animated];
if (!maskLayer)
{
maskLayer = [CAGradientLayer layer];
CGColorRef outerColor = [[UIColor colorWithWhite:0.0 alpha:1.0] CGColor];
CGColorRef innerColor = [[UIColor colorWithWhite:0.0 alpha:0.0] CGColor];
maskLayer.colors = [NSArray arrayWithObjects:
(__bridge id)outerColor,
(__bridge id)innerColor,
(__bridge id)innerColor,
(__bridge id)outerColor, nil];
maskLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.125],
[NSNumber numberWithFloat:0.875],
[NSNumber numberWithFloat:1.0], nil];
[maskLayer setStartPoint:CGPointMake(0, 0.5)];
[maskLayer setEndPoint:CGPointMake(1, 0.5)];
maskLayer.bounds = self.mainCollectionView.bounds;
maskLayer.anchorPoint = CGPointZero;
[self.mainCollectionView.layer insertSublayer: maskLayer atIndex: 0];
}
}
This creates a nice "fade to black" effect on both sides of my collection view. More colors can be added to the locations & color properties to refine the gradient blend. The start/endpoints determine the direction and location of the gradient.
Try to add two layers of CAGradientLayer on the collection view sublayer:
#import <QuartzCore/QuartzCore.h>
CAGradientLayer *leftShadow = [CAGradientLayer layer];
leftShadow.frame = CGRectMake(0, 0, 100, self.collectionView.frame.size.height);
leftShadow.startPoint = CGPointMake(0, 0.5);
leftShadow.endPoint = CGPointMake(1.0, 0.5);
leftShadow.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.4f] CGColor], (id)[[UIColor clearColor] CGColor], nil];
[self.collectionView.layer addSublayer:leftShadow];
CAGradientLayer *rightShadow = [CAGradientLayer layer];
rightShadow.frame = CGRectMake(CGRectGetWidth(self.collectionView.frame)-100.0, 0, 100, self.collectionView.frame.size.height);
rightShadow.startPoint = CGPointMake(1.0, 0.5);
rightShadow.endPoint = CGPointMake(0, 0.5);
rightShadow.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.4f] CGColor], (id)[[UIColor clearColor] CGColor], nil];
[self.collectionView.layer addSublayer:rightShadow];
I am using the following code to set the gradient color to the background of label but no effect what i am doing wrong?
Code is here:
[self.teamName setTextColor:[UIColor whiteColor]];
[self.teamName setBackgroundColor:[UIColor clearColor]];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.teamName.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.teamName.layer insertSublayer:gradientLayer atIndex:0];
It working fine when i insert the CAGradientLayer to the main view.
[self.teamName setTextColor:[UIColor whiteColor]];
[self.teamName setBackgroundColor:[UIColor clearColor]];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.teamName.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.view.layer insertSublayer:gradientLayer atIndex:0];
So I was attempting to do this also! I finally made it work by just placing a UIView behind the label and changing the label background color to clear. I did this in a storyboard.
I want rectangular corners on my cells.
I implemented
cell.backgroundView = [[UIView alloc] initWithFrame:cell.bounds];
as suggested in this comment, but when I tap the cell, the highlight has still rounded corners... How can I get rid of those?
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
... and to mimic the highlight, you'd have
#import <QuartzCore/QuartzCore.h>
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = cell.bounds;
gradient.colors = [NSArray arrayWithObjects:[[UIColor colorWithRed:0. green:0.545 blue:0.941 alpha:1] CGColor], [[UIColor colorWithRed:0.027 green:0.353 blue:0.878 alpha:1] CGColor], nil];
[cell.selectedBackgroundView.layer insertSublayer:gradient atIndex:0];
It's not perfect - still checking why it draws over the right boundary of the cell in portrait and does not scale in landscape when I rotate the device...
Suggestions welcome.
I am looking to create a CAGradientLayer with rounded corners. I can't use .cornerRadius because I would like to round only the top two corners. Also, I cannot use .mask because I would like to take a screenshot of it afterwards and renderInContext does not support CALayer masks.
How can I either:
A: Create an CALayer with a gradient and two rounded corners without using masks
or
B: Take a screenshot similar to UIGraphicsGetImageFromCurrentImageContext, but respecting the mask.
I figured out a programmatic approach to doing this. It involves creating a rounded layer then drawing a square layer on top of it. You'll have to do some playing around with the gradient colors and positions to get something that looks good.
NOTE: Not sure if this solution will work for you given your requirement about masks
+ (void)makeGradientButton:(UIButton *)button {
// Create a rounded layer
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = button.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
gradient.cornerRadius = 8.0f;
// Now create a square layer that draws over the top
CAGradientLayer *gradient2 = [CAGradientLayer layer];
gradient2.frame = CGRectMake(0, 9, button.bounds.size.width, button.bounds.size.height-9);
gradient2.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor redColor] CGColor], nil];
gradient2.cornerRadius = 0.0f;
[gradient setMasksToBounds:YES];
[button.layer insertSublayer:gradient atIndex:0];
[button.layer insertSublayer:gradient2 atIndex:1];
[button setBackgroundColor:[UIColor clearColor]];
}
i would like to ask you, if somebody know how to create a shadow at the end of table view as it is shown in the image bellow (click on the href :)). Best regards
Martin
App with shadow
The code for the top gradient, don't forget to import QuartzCore/QuartzCore.h
The .view is view controllers outlet View (UIView), the table view is it's subview.
- (void)viewDidLoad
{
UIView *gradientView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)] autorelease];
CAGradientLayer *gradient = [CAGradientLayer layer];
[gradient setFrame:gradientView.bounds];
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor clearColor] CGColor], nil];
[self.view.layer addSublayer:gradient];
[super viewDidLoad];
}
Or you can always draw the gradient image and add it as a subview (on the root view after the scroll view, not on the scroll view directly to prevent the image from scrolling).