I am setting the barColor of my UISearchBar to the same color that my navigation bar is set to. When I get back the results in the UI the colors do not match. I have translucent set to YES for both the searchbar and the navigation bar.
Can anyone tell me how I can get the color of the searchbar to match the nav bars color?
The easiest way I have found to accomplish this is by using an image instead of just a color.
[mySearchBar setBackgroundImage:[UIImage imageWithColor:[UIColor blackColor] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
imageWithColor: is a category method I wrote on UIImage that looks like this:
+ (UIImage *) imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Doing this, I am able to get the UISearchBar background to match the UINavigationBar background exactly.
You can just set the backgroundColor of the UISearchBar to UIColor.clearColor(). Then the barTintColor will come through as you expect.
I answered another SO question that is very similar to this one. Just setting translucent to NO won't do the trick. You have to slightly alter your color you use for the UISearchBar when you set it for the UINavigationBar. Check out my full answer here.
Related
I am using FSCalendar What I want to do is change the way of showing events. I want to put a coloured rectangle border around the cell with events. I did that by editing the cell background layer and worked fine, but now I realized that it is the wrong place to put my code as updating to the latest version of FSCalendar which will override my changes.
One of what I can access by the calendar delegates is to set image to the cell, So I want to create image as rectange border with the event colour.
Here is an image of what I want:
Any suggessions is appreicated.
Thanks in advance.
This method will draw a bordered rectangle. I would make it class method and put into UIImage category for convenient use.
- (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)imageSize andBorderWidth:(CGFloat)borderWidth fillWithColor:(BOOL)fillWithColor{
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, imageSize.width, imageSize.height);
if(fillWithColor) {
[color setFill];
CGContextFillRect(context, rect);
} else {
[color setStroke];
CGContextStrokeRectWithWidth(context, rect, borderWidth);
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
EDIT: Added fillWithColor parameter
You can set border for UIImageView instead of set image as rectange border
cell.imageView.layer.borderColor = [[UIColor redColor] CGColor];
cell.imageView.layer.borderWidth = 1.0f;
I want to capture UIView and save as image. Here is my code
+ (UIImage *)captureView:(UIView *)view {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
// CGContextRef context = UIGraphicsGetCurrentContext();
// CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]);
// CGContextFillRect(context, view.bounds);
UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
It works fine. But I get one issue: I can not change background for that image. It always gets black background.
So, how to change background?
Thanks.
The reason why you cannot change the background for a UIImage is because UIImage does not possess a background attribute. To add a background for which you can change color, you're going to have to create a custom UIView on your own for which the UIImage can be placed on top of. So for example, let's say you wanted to create a function which returns an image with a background of your choice:
- (UIImage* )setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect{
// tcv - temporary colored view
UIView *tcv = [[UIView alloc] initWithFrame:rect];
[tcv setBackgroundColor:backgroundColor];
// set up a graphics context of button's size
CGRectGSize gcSize = tcv.frame.size;
UIGraphicsBeginImageContext(gcSize);
// add tcv's layer to context
[tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
// create background image now
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
// [tcv release];
}
// [view drawViewHierarchyInRect:view.frame afterScreenUpdates:NO]; // comment this line
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; // use this line
it gives the actual color of the view's as it is.. if your view's background color is clear color or black color, the image background color will be black color
I tried to draw a custom UINavigationBar via drawRect on iOS7. With the changes of the Navigationbar and the Statusbar my draw begins on y-origin 20.0, not on my 0.0 behind the Statusbar. I checked the wwdc videos but I only found examples with images not with custom draw. Any ideas? Do I need to set some parameters in my subclass?
create a new project based on "Master-Detail Application"
create a sublass for UINavigationBar
change the UINavigationBar in Main.storyboard to the custom class
turn off translucent [self setTranslucent:NO];
add a real simple drawRect to the sublass of UINavigationBar
I made a simple test:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIBezierPath* maskPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 0, 320, 64)];
[maskPath closePath];
[[UIColor greenColor] setFill];
[maskPath fill];
CGColorSpaceRelease(colorSpace);
The green NavigationBar begins under the Statusbar, how can I draw by starting behind the Statusbar?
CURRENT SOLUTION:
#Redwarp posted one way, I made also a simple version to test:
CustomBGView *testView = [[CustomBGView alloc] initWithFrame:CGRectMake(0, 0, 320, 64)];
RetinaAwareUIGraphicsBeginImageContext(testView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[testView.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:image forBarPosition:UIBarPositionTop barMetrics:UIBarMetricsDefault];
Inside the custom UIView you can draw like you want and your custom view appears also behind the StatusBar.
I found a solution, which is a bit peculiar : I subclass the UINavigationBar, and in the onLayoutSubviews, I create the background I want to create, and set it as background image. So I do the equivalent of the drawRect, but in a UIImage that I set as background.
Then, in the xib or storyboard, I select my subclass as the type of the Navigation bar.
Here goes :
#implementation MyNavigationBar
- (void)layoutSubviews {
[super layoutSubviews];
CGPoint origin = [self.superview convertPoint:self.frame.origin toView:nil];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.bounds.size.width, self.bounds.size.height + origin.y), NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height + origin.y));
[self.baseImage drawInRect:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
// If you don't want the bar shadow, set the shadow image as null
[self setShadowImage:[UIImage new]];
}
And whenever you wan't to change the image, you call [navigationBar needsLayout], and it will call layoutSubviews again
EDIT : The trick is getting the origin of the nav bar. If there is a status bar, the origin will be of y 20. If no status bar, it will be 0. So you add the origin.y to the height of the image your drawing into, and you will have a nice result.
//inside init
_color = [UIColor orangeColor];
self.backgroundColor = [UIColor clearColor];
self.clearsContextBeforeDrawing = NO;
//inside drawRect
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextAddEllipseInRect(ctx, rect);
CGContextSetFillColorWithColor(ctx,
_color.CGColor);
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
The background keeps showing up as white rather then transparent. The ellipse also does not change color and shows up as black. Thank in advance to anyone who takes a look.
I think you can refer to this answer for your transparency issue :
Setting A CGContext Transparent Background
As for your ellipse color issue, it correctly display as an orange ellipse on my simulator so you may check at possible overlays or other possible side effects from other parts from your code.
I want to make a clean white Design. So, I set the tintColor property to whiteColor, but there are these dark Lines under the UINavigationBar and UISearchBar.
Do some one know, how to remove the dark Lines or how to change the Color?
add a method to UIImage by category
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
and just set
[self.navigationController.navigationBar setShadowImage:[UIImage imageWithColor:[UIColor whiteColor]]];
This is what I did, and seemed to work, it is a further development of this link. I changed the explicit width declaration to a dynamic one, so that it will be the size of the view if you change view size or not:
UIView *overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 43, self.view.frame.size.width, 1)];
[overlayView setBackgroundColor:[UIColor whiteColor]];
[navBar addSubview:overlayView]; // navBar is your UINavigationBar instance
[overlayView release];
I found the stuff here:
How to remove UINavigatonItem's border line
From iOS 7 UINavigationBar has a shadowImage property that you can set to nil.