UINavigationBar with image and default gradient background with iOS5 - image

I'm attempting to use the new [UINavigationBar appearance] functionality in iOS5 to add a logo image to the UINavigationBars in my application. Primarily, I'd like to keep the default gradient, but center a transparent png in the NavBar. The logo image is roughly 120 pixels wide (240 pixels#2x).
I have first attempted this by setting the background image. The default behavior for setBackgroundImage:forBarMetrics: appears to be to tile the image, and all transparent parts show the default navbar background color, black. I can also set the background color via the appearance modifier, and get a flat color background, but I'd really like to get the original gradient behavior without maintaining a separate image resource for it. It also makes it easier to adjust in code, since I can adjust the tint there, rather than re-generating a new image if I decide to change it.
What I'm trying to use:
UIImage *logoImage = [UIImage imageNamed:#"logoImage"];
[[UINavigationBar appearance] setBackgroundImage:logoImage forBarMetrics:UIBarMetricsDefault];

You can do this two ways. If you want to always have the image in the navigation bar, then create an image view and set it as a subview of the navigation bar:
[self setLogoImageView:[[UIImageView alloc] init]];
[logoImageView setImage:[UIImage imageNamed:#"logo.png"]];
[logoImageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect navFrame = [[navController navigationBar] frame];
float imageViewHeight = navFrame.size.height - 9;
float x_pos = navFrame.origin.x + navFrame.size.width/2 - 111/2;
float y_pos = navFrame.size.height/2 - imageViewHeight/2.0;
CGRect logoFrame = CGRectMake(x_pos, y_pos, 111, imageViewHeight);
[logoImageView setFrame:logoFrame];
[[[self navigationController] navigationBar] addSubview:logoImageView];
If you only want to display the logo in a certain view, then set the view's navigation item:
[logoImageView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
[[self navigationItem] setTitleView:logoImageView];

Related

Drawing correct CALayer colors honoring NSAppearance

I am looking into theming my app by setting window.appearance.
In my app, I draw some stuff inside layers. I also use Core Plot, which renders its charts in layers.
For the default aqua appearance, I just use the system colors (such as NSColor.textColor and NSColor.gridColor) and they are drawn in the correct color in CALayer. But changing the window's appearance to vibrant dark causes colors to be drawn incorrectly.
Is there any way to obtain the correct color for a givenNSAppearance? Private API is acceptable too.
If the question is not clear, here is a very simple example to show the problem.
I set up a CATextLayer that is added as a sublayer of the main view's sublayers and an NSTextFied that is added as a subview:
CATextLayer* textLayer = [CATextLayer new];
textLayer.string = #"Is this colored correctly? (Layer)";
textLayer.foregroundColor = NSColor.textColor.CGColor;
textLayer.contentsScale = 2.0;
textLayer.frame = (CGRect){0,0, [textLayer preferredFrameSize]};
NSTextField* textField = [NSTextField new];
textField.stringValue = #"Is this colored correctly? (View)";
textField.textColor = NSColor.textColor;
textField.font = (__bridge id)textLayer.font;
textField.editable = NO;
textField.selectable = NO;
textField.bezeled = NO;
textField.backgroundColor = nil;
[textField sizeToFit];
textField.frame = (CGRect){0, 60, textField.bounds.size};
[self.view.layer addSublayer:textLayer];
[self.view addSubview:textField];
On an Aqua window, both appear correctly:
However, on a dark vibrant window, the layer does not, while the text field does:
I'd like to know how to get the correct color for a given NSAppearance.
So I had an incorrect approach.
The right way to do it, is to implement -updateLayer in the view and take the colors' CGColor snapshot there. -updateLayer is called when the appearance changes, so the view can update it with the correct color values.

NSButton corner radius and NSPopover

I'm using an NSPopover and I'm putting a NSViewController inside to be displayed as a custom view from a NSStatusItem. Most of the view controller displays correctly except for the NSButton that have a corner radius on them. There is some extra white leaking out where the rounded corners are being applied. Displaying the buttons within the actual app, this problem doesn't occur.
I feel it has to do something with the NSPopover appearance which I have set to "NSAppearanceNameAqua".
The NSButtons are within a NSView which are displayed in a NSTableView and are set to this style.
self.createdButton.wantsLayer = true
self.createdButton.layer?.backgroundColor = Utils.blackColor().CGColor
self.createdButton.layer?.masksToBounds = true
self.createdButton.layer?.cornerRadius = 5
The top image is when the actual app is open.
The bottom image is when the view controller is being shown within a NSPopover.
create corner radius using bezier path i.e.
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:view.bounds xRadius:3 yRadius:3];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = view.bounds;
maskLayer.path = path.toCGPath;
self.containerView.layer.mask = maskLayer;

Hide UISlider track when behind transparent thumb image

I'm currently creating a custom UISlider in Xcode. I am setting the thumb Image, min Image, and max Image for the slider. Everything works great. The design calls for the thumb image to be transparent to the background of the view. This is where my problem comes in, you can see the two sides of the slider coming together in the middle of the thumb image. I don't want it to look like this. I want the slider bars to stop a the edge of the thumb image. Any ideas as to how I can accomplish this? Any and all suggestions are welcome. Thanks.
This is the Code I'm using so far.
UIImage *thumbImage = [UIImage imageNamed:#"thumb.png"];
UIImage *minImage = [UIImage imageNamed:#"min.png"];
UIImage *maxImage = [UIImage imageNamed:#"max.png"];
minImage = [minImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
maxImage = [maxImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
[_slider setMinimumTrackImage:minImage forState:UIControlStateNormal];
[_slider setMaximumTrackImage:maxImage forState:UIControlStateNormal];
[_slider setThumbImage:thumbImageforState:UIControlStateNormal];
I can't Post an image because I don't have enough reputation. I'll try to explain a little better. I have a Thumb Image that is a circle. The center of the circle is transparent and you can see right to the background image of my view. The track for the slider continues all the way to the center of the circle. I'd prefer if the track stopped at the outline of the circle. I hope that makes more sense.
I have not received any suggestions as to how to hide the slider track when it is behind the thumb image so I am posting my solution incase someone else has this problem. If anyone has a better way of doing this please let me know.
In order to have a transparent thumb image and not have the track connect in the center of it I had to set the slider track images to blank images and setup my own slider track image that is just going to be resized every time the value of the slider changes. Not only will I be changing the width of the custom slider track but I also will have to update the X position of the image every time I resize it so that it will connect with the end image of my slider track.
In my case I have a slider that is set to 0 and its Max is set to the Width of the slider. My custom slider track is only going to appear on the right side of the thumb image. So as you slide the thumb image to the right the bar shrinks and the left side is clear.
First I setup my Slider Thumb Image and Set the Slider Track to Blank Images.
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *thumbImage =[UIImage imageNamed:#"answerSlider.png"];
[_slider setMinimumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setMaximumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setThumbImage:thumbImage forState:UIControlStateNormal];
thumbImage = nil;
_slider.value = 0;
}
In the ViewWillApear I have a call to setup my custom SLider track that I will create.
- (void)viewDidAppear:(BOOL)animated{
[self updateSlideBarLength];
}
Inside updateSLideBarLength I Use the value of the slider to help determine the width of my slider track Image.
- (void)updateSlideBarLength{
// Get Position Of Slider
CGFloat sliderValue = _slider.value;
CGFloat thumbImageWidth = 58; // this is the width of my thumb image
CGFloat sliderControlWidth = 288.0f; // This is a constant number in my case
CGFloat sliderWidth = sliderControlWidth - thumbImageWidth - sliderValue;
CGFloat sliderBarHeight = 2.0f;
// Reset Width Of aFrame
CGFloat sliderEndY = _sliderEnd.frame.origin.y;
CGFloat sliderEndX = _sliderEnd.frame.origin.x;
CGFloat sliderBarY = sliderEndY + (_sliderEnd.frame.size.height / 2 - 1);
CGFloat sliderBarX = sliderEndX - sliderWidth + (_sliderEnd.frame.size.width/2);
CGRect aframe = CGRectMake(sliderBarX, sliderBarY, sliderWidth, sliderBarHeight);
if (_sliderBar == nil) {
NSLog(#"Slider Bar Doesnt Exist");
_sliderBar = [[UIImageView alloc] initWithFrame:aframe];
_sliderBar.image = [UIImage imageNamed:#"sliderBar.png"];
[self.view addSubview:_sliderBar];
[self.view bringSubviewToFront:_sliderBar];
}
_sliderBar.frame = aframe;
}
Lastly I make sure the updateSliderBarLength is called every time the slider value changes.
- (IBAction)sliderMoved:(id)sender {
[self updateSlideBarLength];
}
This works although I had to adjust the Max value of my slider so that the custom slider track image I created always lines up with the edge of the thumb Image. While sliding the thumb image as the value increased the more the slider track started to infringe on my thumb image. By increasing the slider value I was able to stop this from happening. Again, I'm not convinced this is the best way to do this but it works for me. Later when I have more Rep and can post Pictures I will edit this post to help everyone visualize what I am describing.
I did something similar to Sean Marraffa, although I found it easier to subclass UISlider and update the frames of my image views in thumbRectForBounds:trackRect:value using something like this:
var trackHeight: CGFloat = 2
override func thumbRectForBounds(bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect
{
let superValue = super.thumbRectForBounds(bounds, trackRect: rect, value: value)
let originY = (bounds.height-trackHeight)/2.0
minTrackImageView?.frame = CGRectMake(0, originY, superValue.minX, trackHeight)
maxTrackImageView?.frame = CGRectMake(superValue.maxX, originY, bounds.width-superValue.maxX, trackHeight)
return superValue
}
minTrackImageView and maxTrackImageView are image views I set up in viewDidLoad.

How to make TabBar transparent

I want to make the tabbar transparent and leave the icons still there. So that when you look at it the icons on the tabbar look like they are their by themselves. Whats the code for me to do this? Right now this is the code i have
UIImage* tabBarBackground = [UIImage imageNamed:#""];
[[UITabBar appearance] setBackgroundImage:tabBarBackground];
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#""]];
Try this code
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = CGRectMake(0.0, 0, self.view.bounds.size.width, 48);
UIView *trans_view = [[UIView alloc] initWithFrame:frame];
[trans_view setBackgroundColor:[[UIColor alloc] initWithRed:0.0
green:0.0
blue:0.0
alpha:0.5]];//you can change alpha value also
[tabBar1 insertSubview:trans_view atIndex:0];//tabBar1 = your tabbar reference
[trans_view release];
}
this link also will help you
The easiest way to make a tab bar transparent is by setting the tab bar background image to a transparent image in the interface builder.
You can get a transparent png image whose height and width is equal to the tab bar's from the net.
Note: By changing the alpha value, you actually end up dimming the tab bar's icons as well. Make sure this is what you want, otherwise using a transparent background image is a better option.

How do i make a simple scrollview height = 80, width = 280, with images inside thats scrolls horizontally?

I need to make a simple scroll view in xcode with width of 280 and height of 80 and with images inside thats scrolls horizontally. i want to make this programmatically.
I assume you mean the UIScrollview, which has a guide written by apple found here:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html
A guide that I personally used was this one:
http://idevzilla.com/2010/09/16/uiscrollview-a-really-simple-tutorial/
I'll take you through the quick basics of adding the scrollview to your view and adding images to it.
I'm guessing you're new to Objective C, so I'll give you a quick guide. Firstly, you'll want to make a UIScrollView object. This is done by declaring the following:
UIScrollView *aScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake (0,0,320,250)];
You'll notice I set the frame. The first two numbers of CGRectMake give you the x and y origin of the point while the last two numbers are for how wide and tall you want your object to be.
Afterwards, you'll want to add images to it. You'll need a UIImageview.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 250)];
Note that I positioned the image at 0,0, giving it a height of a 250 and a width of 320. This ensures that it fills entire scrollview's initial view.
imageView.image = [UIImage imageNamed:#"foo.png"];
You'll attach an image to the imageView. But wait, there's more. So far you've created these objects but have not yet associated them with the view. So if we are in a ViewController class (you'll have to look up what that is), the ViewController contains a view. We can attach our objects to the view.
[aScrollView addSubview:imageView]; // Adds the image to the scrollview
[self.view addSubview:aScrollView]; // Adds the scrollview to the view.
If you want to add more images, you have to add them at different x origins. So our first added image was at 0,0. Our next added image should be at 320,0 (because the first image took up 320 pixels width).
UIImageView *secondImageView = [[UIImageView alloc] initWithFrame:CGRectMake(320, 0, 320, 250)];
secondImageView.image = [UIImage imageNamed:#"bar.png"];
[aScrollView addSubview:secondImageView];
There are a number of options for scrollview that you will want to explore. The ones I found useful were:
aScrollView.delegate = self; // For gesture callbacks
self.pagingEnabled = TRUE; // For one-at-a-time flick scrolling
self.showsHorizontalScrollIndicator = NO; // Cleaner look for some apps.
self.alwaysBounceHorizontal = TRUE; // Look it up.

Resources