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.
Related
Just started to use Xcode 9 and iOS 11 today, I found there is border line created about 3 px above the bottom of navigation bar. I never seen same thing in iOS 10. Any idea how to remove it? To make it clear it is not the iPhone X home button in the screenshot below, but the line in the navigation bar
I found the answer: there is a bottom shadow line created by the navigation bar which can't be accessed directly, and I have to write code replace the image for that shadow. For anyone run into the same problem, this is the code:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"11.0")) {
// Remove navigation bar bottom shadow line in iOS 11
[self.navigationBar setBackgroundImage:[self generateSinglePixelImageWithColor:[FillrThemeManager sharedInstance].theme.fillViewNavigationBarTintColor] forBarMetrics:UIBarMetricsDefault];
self.navigationBar.shadowImage = [self generateSinglePixelImageWithColor:[UIColor clearColor]];
}
- (UIImage *)generateSinglePixelImageWithColor:(UIColor *)color {
CGSize imageSize = CGSizeMake(1.0f, 1.0f);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0f);
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(theContext, color.CGColor);
CGContextFillRect(theContext, CGRectMake(0.0f, 0.0f, imageSize.width, imageSize.height));
CGImageRef theCGImage = CGBitmapContextCreateImage(theContext);
UIImage *theImage;
if ([[UIImage class] respondsToSelector:#selector(imageWithCGImage:scale:orientation:)]) {
theImage = [UIImage imageWithCGImage:theCGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
} else {
theImage = [UIImage imageWithCGImage:theCGImage];
}
CGImageRelease(theCGImage);
return theImage;
}
I currently have the following image on which I am trying to set a border. It consists of an UIImageView with an image inside (a transparent.png)
When I try to set the border for my image (see code), it gives a border to the UIImage, but it doesn't 'snap' around my image. Is it possible to achieve that effect?
See image current implementation here.
- (UIImage*)imageWithBorderFromImage:(UIImage*)source;
{
CGSize size = [source size];
UIGraphicsBeginImageContext(size);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
[source drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.5, 1.0, 1.0);
CGContextStrokeRect(context, rect);
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}
Try Adding a layer behind UIImageView and add a border to it that will do the trick
#define kBorderWidth 3.0.
#define kCornerRadius 8.0
CALayer *borderLayer = [CALayer layer];
CGRect borderFrame = CGRectMake(0, 0, (imageView.frame.size.width), (imageView.frame.size.height));
[borderLayer setBackgroundColor:[[UIColor clearColor] CGColor]];
[borderLayer setFrame:borderFrame];
[borderLayer setCornerRadius:kCornerRadius];
[borderLayer setBorderWidth:kBorderWidth];
[borderLayer setBorderColor:[[UIColor redColor] CGColor]];
[imageView.layer addSublayer:borderLayer];
And don't forget to import QuartzCore/QuartzCore.h
This example will draw a boarder on the layer, but change it's frame slightly to make the border around the layer.
Depending on your needs, if you don't want it to be as accurate as possible, a quick and dirty solution could be something like this:
- (UIImage *)borderedImageFromImage:(UIImage *)source andColor:(UIColor *)borderColor{
CGFloat scale = 0.95;//this determines how big the border will be, the smaller it is the bigger the border
UIImage *borderImage = [source imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(source.size, NO, source.scale);
[borderColor set];
[borderImage drawInRect:CGRectMake(0, 0, source.size.width, source.size.height)];
[source drawInRect:CGRectMake(source.size.width*(1-scale)/2,
source.size.height*(1-scale)/2,
source.size.width * scale,
source.size.height * scale)];
borderImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return borderImage;
}
and here is how to use it:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.heartImageView.image = [self borderedImageFromImage:[UIImage imageNamed:#"heart"] andColor:[UIColor blackColor]];
}
What this essentially does is draw the image you want twice, once in the colour of the border (slightly scaled) and once with the normal colour. Your mileage may vary depending on the image.
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.
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.
I'm trying to draw a straight dashed line. I've gotten it so it draws the dashes, but this black background color remains. I've seem many answers to other questions, but none of them worked.
Apple's documentation seems to point to the fill color and using either CGContextFillPath or CGContextDrawPath, but neither of those work and the background of the dashed line is still black.
- (void)drawRect:(CGRect)rect {
CGContextRef contextRef = UIGraphicsGetCurrentContext();
GLFloat lines[] = {self.frame.size.width, self.frame.size.width*2};
CGFloat grey[4] = {0.6f, 0.6f, 0.6f, 1.0f};
CGContextSetStrokeColor(contextRef, grey);
CGContextSetFillColorWithColor(contextRef, [[UIColor clearColor] CGColor]);
CGContextSetLineDash(contextRef, 0, lines, 2);
CGContextSetLineWidth(contextRef, self.frame.size.width);
CGContextBeginPath(contextRef);
CGContextMoveToPoint(contextRef, 0, 0);
CGContextAddLineToPoint(contextRef, 0, self.frame.size.height);
CGContextDrawPath(contextRef, kCGPathFillStroke);
}
When manually adding this view to your view hierarchy, you just have to make sure you're setting the background color. For example, if you're initializing your view with initWithFrame, then set the background color in that method:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
Or, alternatively, when adding the view, set the background color there:
CustomView *customView = [[CustomView alloc] initWithFrame:frame];
customView.backgroundColor = [UIColor clearColor];
[self.view addSubview:customView];