(edited: added more information at bottom)
Firstly I have looked through similar posts and tried their answers but with no luck :( I have a custom navigation bar (just a custom background image) and I'm trying to add a custom back button.
// custom back button.
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backImg = [UIImage imageNamed:#"btn_back.png"];
backBtn.titleLabel.text = #"";
[backBtn setBackgroundImage:backImg forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(backPressed) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 54, 33);
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
self.navigationItem.leftBarButtonItem.title = #"";
The above code is meant to add the button but it does not display on the nav bar. I can still click the area where its meant to appear and it does bring me back to the previous view?! removing the above code displays the standard back button.
Any ideas? Thanks in advance!
(edit)
Hi again guys,
I tried all your suggestions and still no luck :( I probably should have mentioned earlier that I have a custom nav bar image using the following code. This might be affecting the display of my custom back button image.
This code displays a custom image depending upon a parameter I set. Thanks again for further help!
// custom navigation bar image
#implementation UINavigationController (CustomImage)
// set the background image for the nav bar.
- (void) setCustomNavBar:(NSInteger)screen {
UIImage *navBarImg;
switch (screen) {
case kCreateHuntScreenIdentifier:
navBarImg = [UIImage imageNamed:#"title_create-hunt.png"];
break;
case kCreateLocationsScreenIdentifier:
navBarImg = [UIImage imageNamed:#"title_create-location.png"];
break;
case kListNewLocationsScreenIdentifier:
navBarImg = [UIImage imageNamed:#"title_choose-location.png"];
break;
default:
break;
}
UIImageView *imgView = [[UIImageView alloc] initWithImage:navBarImg];
[[[self.navigationBar subviews] objectAtIndex:0] removeFromSuperview];
[self.navigationBar addSubview:imgView];
[imgView release];
}
#end
Thanks again for all your advice! I finally found a solution :D
Very quickly I needed to be able to change the background image for a navigation bar from view to view when I pushed or popped the stack.
Using the most popular methods such as overriding the UINavigationBar's drawRect would only partly work, it would work on the root view but then push the image to the front of the navigation bar's stack for every other screen no matter if I sent it to the back, etc.
I found the solution here: http://sebastiancelis.com/2009/12/21/adding-background-image-uinavigationbar/
Take a read, it works great :)
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundImage:[UIImage imageNamed:#"imgname.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(method_name:) forControlEvents:UIControlEventTouchUpInside];
btn.frame=CGRectMake(3, 2, 53, 30);
UIBarButtonItem *btnBack=[[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.leftBarButtonItem=btnBack;
[btnBack release];
[btn release];
Try,
self.navigationItem.hidesBackButton = YES;
befor writing the code for .leftBarButtonItem .Hope it helps
Related
I have a UICollectionView that displays image thumbnails. When clicked, the thumbnails call another view, wallpaperView, to show the image in full size.
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// ...insert the usual row number check here
UIViewController *wallpaperView = [QUOWallpaperViewController new];
[self.navigationController pushViewController:wallpaperView animated:YES];
}
(The UICollectionView itself is the root view controller of a UINavigationController object, as per usual)
Now, in wallpaperView, I want to hide the navigation bar, and display my own custom button. I have already found a solution here.
Following the top answer there, I put this code in wallpaperViewController.m:
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
}
However, this does not work. The navbar still shows up as usual. Does anyone know why this is the case?
if you need to show your own button as bar button on navigation then there is no need to hide navigationbar i've gone through your code and made some modifications just use this one and do not hide navigation bar ok.
UIImage* image3 = [UIImage imageNamed:#"mail-48_24.png"];
CGRect frameimg = CGRectMake(0, 0, image3.size.width, image3.size.height);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:image3 forState:UIControlStateNormal];
[someButton addTarget:self action:#selector(sendmail) forControlEvents:UIControlEventTouchUpInside];
[someButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.rightBarButtonItem=mailbutton;
[someButton release];
self.navigationController.navigationBar.translucent = YES; // Setting this slides the view up, underneath the nav bar (otherwise it'll appear black)
const float colorMask[6] = {222, 255, 222, 255, 222, 255};
UIImage *img = [[UIImage alloc] init];
UIImage *maskedImage = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(img.CGImage, colorMask)];
[self.navigationController.navigationBar setBackgroundImage:maskedImage forBarMetrics:UIBarMetricsDefault];
//remove shadow
[[UINavigationBar appearance] setShadowImage: [[UIImage alloc] init]];
Try by hiding navigation controller
Inside the viewDidLoad method for your class QUOWallpaperViewController
write
[self.navigationController setNavigationBarHidden:YES animated:YES];
You can write this code in ViewDidLoad method.
self.navigationController.navigationBarHidden=YES;
I add UINavigationBar via Library to view. I also add UINavigationItem to this NavigationBar.
In viewController.m,I added the following code but back button doesn't show.
self.navigationItem.title = #"List";
self.navigationItem.backBarButtonItem.title = #"Back";
Try this:
self.navigationItem.leftItemsSupplementBackButton = YES;
or
navigationItem.leftItemsSupplementBackButton = true
If you customize your navigation controller with UIBarButtonItems the framework removes the back button by default, since it assumes you are customizing the Navigation bar. Use that line to add the back button in again.
self.navigationItem.backBarButtonItem will be shown only after your have pushed another one view to navigation stack, controlled by self.navigationController, if no left button on navigation bar is displayed.
From Apple docs:
When this item is the back item of the navigation bar—when it is the next item below the top item—it may be represented as a back button on the navigation bar. Use this property to specify the back button. The target and action of the back bar button item you set should be nil. The default value is a bar button item displaying the navigation item’s title.
Try this code,
**To hide your default back button use this,**
self.navigationItem.hidesBackButton = YES;
UIImage* image = [UIImage imageNamed:#"back.png"];
CGRect frame = CGRectMake(0, 0, image.size.width, image.size.height);
UIButton* backbtn = [[UIButton alloc] initWithFrame:frame];
[backbtn setBackgroundImage:image forState:UIControlStateNormal];
[backbtn setShowsTouchWhenHighlighted:YES];
[backbtn addTarget:self action:#selector(goBack) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem* backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backbtn];
[self.navigationItem setLeftBarButtonItem:backButtonItem];
[backButtonItem release];
[backbtn release];
Action Event for back button:
-(IBAction)goBack{
//ur code here
}
Try this code may be it's help to u
UIButton *moreButton1 = [UIButton buttonWithType:UIButtonTypeCustom];
[moreButton1 setImage:[UIImage imageNamed:#"left_arrow.png"] forState:UIControlStateNormal];
//[moreButton setImage:[UIImage imageNamed:#"Button_OtherInfo_Active.png"] forState:UIControlStateHighlighted];
[moreButton1 addTarget:self action:#selector(backClick) forControlEvents:UIControlEventTouchUpInside];
[moreButton1 setFrame:CGRectMake(0, 0, 50,30)];
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc] initWithCustomView:moreButton1];
put this code in viewDidLoad
-(void)backClick
{
[self.navigationController popViewControllerAnimated:YES];
}
This is a bit old, but in case someone is looking for an answer...
The back button shows up automatically, but the current view (not the one being pushed) needs to have a title. eg:
- (void)viewDidLoad
{
self.title = #"Home";
[super viewDidLoad];
}
Then, when you push a view onto the view stack with
[self.navigationController pushViewController:aViewController animated:YES];
the back button shows up. No need to mess with UINavigationItem or UINavigationBar. Use those to customize the navigation bar. Take a look at the example project called NavBar, part of xcode.
how can i customize the navigation bar or add the background image in it and buttons of navigation bar?
please tell me in simple way not make the answer hard to understand i am not expert and?
explain step by step.
Follow this tutorial: How do iPhone apps Instagram/Reeder/DailyBooth implement custom NavigationBars with variable width back buttons?. It includes a source code example.
What you're looking for sadly isn't that easy to accomllish. The technique required rather reminds of a workaround than a working solution It's called method swizzling and here is a tutorial on how to apply it on a navbar in order to get a custom background image in there: http://sebastiancelis.com/2009/12/21/adding-background-image-uinavigationbar/
Adding buttons to your navigationbar is fairly easy. Say your navigation bar is instansiated as navigationController:
UIBarButtonItem *yourButton = [[UIBarButtonItem alloc] initWithTitle:#"Hello" style: UIBarButtonStylePlain target:self action:#selector(myTargetMethodSignature:)];
navigationController.navigationItem.rightBarButtonItem = yourButton;
[yourButton release];
Hope this helps.
Wasabi
Add the code in .m file above #implementation
- (void)drawRect:(CGRect)rect {
/ UIImage *image = [UIImage imageNamed: #"navigation_bar.png"];
UIImage *image = [UIImage imageNamed: #"navigationbarnew2.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, 44)];
}
#end
And to add button to navigation bar add the following code in viewdidload
UIImage* image3 = [UIImage imageNamed:#"mail-48_24.png"];
CGRect frameimg = CGRectMake(0, 0, image3.size.width, image3.size.height);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:image3 forState:UIControlStateNormal];
[someButton addTarget:self action:#selector(sendmail)
forControlEvents:UIControlEventTouchUpInside];
[someButton setShowsTouchWhenHighlighted:YES];
mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.rightBarButtonItem=mailbutton;
[someButton release];
I have a custom UINavigationBar that has a different image background and height than the default one. It's displayed normally but as soon as I go back and forth between apps the background image and buttons inside the navigation bar jump up.
The UINavigationBar is created in a nib and has a custom class that overrides the default implementation to add the image:
#implementation MyUINavigationBar
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"nav.png"];
rect.size.height = 60;
[image drawInRect:rect];
}
#end
At this point the bar isn't displayed correctly. In - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions of my app delegate I fix this with this code:
self.navigationController.view.frame = CGRectMake(0, 20, 320, 460);
self.navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 60);
Now everything shows up correctly. When I switch to another app and go back again the bar jumps up, just as if the frames weren't applied. This happens right after I switch back to the app.
Below are two screenshots showing what's going on. The first one shows the correct version, the other one the faulty one.
Any idea what might be going on? I tried applying the new frames in viewWillAppear and viewDidAppear of the active view or in applicationDidBecomeActive of the app delegate but that didn't help.
https://skitch.com/instromaniac/rtagr/ios-simulator
https://skitch.com/instromaniac/rtaf9/view-not-ok
I spent days to figure this out, here is the trick that really work for a complete, customized backButton.
The backBarButtonItem is totally locked down in the iOS SDK (4.3 as far as I know), so we have to use a leftBarButtonItem that do the job in place of the regular back button.
Whereas the backBarButtonItem has to be defined in the Root View Controller of your UINavigationController, we have to setup our fake BackButton in the child view (ie. nextViewController in my example).
This code is in my Root View Controller (Which is a UITableViewDelegate), in -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[[self navigationController] pushViewController:nextViewController animated:YES];
here is the graal for displaying our fake back button in a 70px Custom UINavigationBar (Play with the frames to fit your needs) :
-(void)handleBack:(id)sender {
// Simulate the original back button
[self.navigationController popViewControllerAnimated:YES];
}
-(void)viewWillAppear:(BOOL)animated {
// Making a custom button
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[backBtn setImage:[UIImage imageNamed:#"back-button.png"] forState:UIControlStateNormal];
[backBtn setImage:[UIImage imageNamed:#"back-button-hover.png"] forState:UIControlStateHighlighted];
[backBtn setImage:[UIImage imageNamed:#"back-button-disabled.png"] forState:UIControlStateDisabled];
[backBtn setFrame:CGRectMake(6, 4, 60, 30)];
// Binding custom target & action to the button
[backBtn addTarget:self action:#selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
// Nesting the button in a UIView to position the button anywhere!
UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 70)];
[backView addSubview:backBtn];
// Nesting all of these into a UIBarButtonItem
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backView];
// Overwrite original backbutton (self.navigationItem.backBarButtonItem DO NOT WORK HERE
self.navigationItem.leftBarButtonItem = backItem;
// Memory clean up
[backItem release];
[backView release];
}
Have fun ;)
Try changing the frame of the navigation controller's view as
self.navigationController.view.frame = CGRectMake(0,0,320,480);
Hope this helps
Ive got an iPhone/iPad universal application and I wanted to have a custom navigation bar where the top half of the nav bar contained our companies logos, and the bottom half was the standard navigation bar.
I figured out how to do this, showing in the code below, but my UIButton "logosButton" doesnt always respond to being clicked, it appears as though only certain parts of the button are active, and others dont do anything at all... I cannot figure out why this is.
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview: navController.view];
float width = IS_IPAD ? 768.0f : 320.0f;
float logosHeight = IS_IPAD ? 20.0f : 20.0f;
float barHeight = IS_IPAD ? 32.0f : 32.0f;
self.navBar = [[UINavigationBar alloc] initWithFrame: CGRectMake(0.0f, logosHeight, width, barHeight)];
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, logosHeight)];
UIButton *logosButton = [[UIButton alloc] init];
[logosButton setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState:UIControlStateNormal];
[logosButton setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState:UIControlStateHighlighted];
[logosButton addTarget:self action:#selector(logosButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[logosButton setFrame: CGRectMake(0, 0, width, logosHeight)];
[tempView addSubview: logosButton];
[[self view] addSubview: tempView];
[tempView release];
[[self view] addSubview: self.navBar];
self.navItem = [[UINavigationItem alloc] initWithTitle: #"Home"];
[self.navBar pushNavigationItem:self.navItem animated:NO];
}
The method: logosButtonClicked does get fired every now and then when I click on the UIButton, but I clearly am clicking on certain spots where nothing happens at all...
Very frustrating, I dont seem, to see a pattern in regards to where its active, but could someone please help out here?
EDIT
I think I have just stumbled across something, I changed the button to a UIButtonTypeRoundedRect and got rid of the images (and also made it larger) and it appears that I cannot click on the bottom OR top sections of the button where the button is rounded. So the middle rectangular section is the only section where I can click... why would this be?
EDIT 2
For anyone reviewing this question, please see taber's latest edit on his answer. The Navigation Controller is eating touches for some reason, and I need to figure out why this is so, could be a bug?
FINAL ANSWER :)
Okay after reviewing the project it looks like the UINavigationController that is positioned below the button is eating touches globally. Which is definitely weird because it was added as a subview BELOW your button. So there must be some kind of funky frame/touch-eating going on with the UINavigationController. I tried to set navigationController.titleView.userInteractionEnabled = NO but to no avail. If anyone knows how to basically make UINavigationController and UINavigationBar not eat touches (I'm talking about the background where no buttons exist) then please chime in. The UIButton touches work just fine when the UINavigationController isn't added to the view.
Original Answer
It may be some other UI elements in [self view] or tempView sitting on top of the button and intercepting taps. You might want to try either commenting out everything else in the view(s) and/or try setting the userInteractionEnabled property on them like this:
[otherUIElement setUserInteractionEnabled: NO];
EDIT:
This code makes it so that you CAN click the round rect edges but NOT the title text. So I suspect that it's some sort of subview preventing the button from catching the tap.
[logosButton addTarget:self action:#selector(logosButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[logosButton setFrame: CGRectMake(0, 0, 320.0, 50.0)];
[logosButton setTitle: #"HELLO" forState: UIControlStateNormal];
[logosButton.titleLabel setUserInteractionEnabled: YES];
EDIT #2:
Try using this subclassed button and see if the issue still occurs:
// NavBtn.h
#interface NavBtn : UIButton {
}
-(id)initWithTitle:(NSString *)text;
#end
// NavBtn.m
#import "NavBtn.h"
#implementation NavBtn
- (id)initWithTitle:(NSString *)text {
if ((self = [super initWithFrame: CGRectMake(0, 0, 320, 50)])) {
[self setTitle: text forState: UIControlStateNormal];
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
[self setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState: UIControlStateNormal];
[self setBackgroundImage:[UIImage imageNamed:#"logo_bar_alone.png"] forState: UIControlStateHighlighted];
}
return self;
}
// i guess you shouldn't need to mess with layoutSubviews
#end
To load it into your view:
#import "NavBtn.h"
... in viewDidLoad, etc ...
NavBtn *btn = [[NavBtn alloc] initWithTitle: #"hey"];
[self.view addSubview: btn];
[btn release];
If THAT doesn't work, there's got to be some kind of third party library doing some funky category overriding of your UIButton class or something.