How to merge two image from edges to look like a single image in iOS? - ios7

I have two imageview. How can i merge this image so it will look like a single image. I tried a lot like creating blur and gradient at the end of first image and at the start of second image even though not getting desired result like below image.
This is normal image.
and this after merging.
How to achieve this result? Please help me.
Thanks in advance.

I got an answer. Use below code and add gradient mask to both images at border. You can shift some pixel of second image view frame upper to first image, so the first image view border and second image view border will merge completely.
-(void)addGradientTo:(UIImageView*)imageView {
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = imageView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithWhite:0 alpha:0.2] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
(id)[[UIColor colorWithWhite:0 alpha:0.2] CGColor], nil];
gradient.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:.1],
[NSNumber numberWithFloat:.9],
[NSNumber numberWithFloat:1], nil];
gradient.startPoint = CGPointMake(0,0.3);
gradient.endPoint=CGPointMake(1,0.3);
[imageView.layer setMask:gradient];
}

Related

Objective C - Faded Gradient on left/right sides of UICollectionView

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];

UITableViewCell with rectangular corners in grouped style

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.

CAGradientLayer with Rounded Top Corners (without using .mask)

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]];
}

Why does the app crash when using CAGradientLayer

I've started using the CAGradientLayer but my app crashes
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = headerView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[UIColor redColor],(id)[UIColor greenColor], nil];
[headerView.layer addSublayer:gradient];
EXEC_BAD_ACESS
Is there an error in my implementation?
It's a small bug - you need to use and array of CGColorRef pointers:
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor], (id)[[UIColor greenColor] CGColor], nil];
CAGradientLayer use CGColorRef values. Use the CGColor property for UIColor. Example:
[UIColor redColor].CGColor

UIView CAGradient with rounded corners?

I have an UIView with rounded corners and drop shadow, implemented and working. But the UIView has a boring background color, white. So I want to put a gradient layer as the background. Below the labels, buttons and most important, make it so the rounded corners still appears.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = subHudView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[subHudView.layer addSublayer:gradient];
subHudView.layer.cornerRadius = 8;
subHudView.layer.masksToBounds = NO;
subHudView.layer.shadowOffset = CGSizeMake(-5, 5);
subHudView.layer.shadowRadius = 8;
subHudView.layer.shadowOpacity = 0.75;
This is my code as I tried to implement it, but the gradient layer is on top of everything in the view know. How can I make the gradient go under all the controls and labels? Every responding help will be appreciated.
in Swift:
let gradientLayer = CAGradientLayer()
gradientLayer.cornerRadius = 20.0
A layer added to your view (addSublayer) is drawn in front of your view's own layer, which is where all your view's drawing takes place. What you want is to draw the gradient into your view's own layer. To do so, implement +layerClass in your view, specifying that you want your view's layer to be a gradient view.
So, for example (in the view's own code):
+(Class)layerClass {
return [CAGradientLayer class];
}
-(void)awakeFromNib {
[super awakeFromNib];
CAGradientLayer* layer = (CAGradientLayer*)self.layer;
layer.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
layer.cornerRadius = 8;
layer.masksToBounds = NO;
layer.shadowOffset = CGSizeMake(-5, 5);
layer.shadowRadius = 8;
layer.shadowOpacity = 0.75;
}
If you then implement drawRect:, however, you'll of course wipe out your gradient and your rounded corners. There are ways around that...
When you addSublayer: it add the layer at the top of all the sublayers.
You should probably use something like that instead :
[subHudView.layer insertSublayer:gradient atIndex:0];
That way, the CAGradientLayer will be below everything else.
As well as the insertSublayer:atIndex: that gcamp suggested, you can also use insertSublayer:above: and insertSublayer:below: to place your layer in specific places.
[self.view.layer insertSublayer:gradient below:someUIObject];
Rather than create a new layer, override your view's layer method:
+ (Class)layerClass
{
return [CAGradientLayer class];
}
This will ensure that your view create a CAGradientLayer, rather than a basic CALayer, as the base layer.
Then, during init get hold of the layer:
CAGradientLayer *gradLayer = self.layer;
gradLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
and assign your gradients to it.
Nice and clean...