I'm very new with iOS Development and I have just created one of my first apps, in my .xib file I have a UINavigationBar that I want to hide/show when a part of the screen is tapped by the user (like in the Photo app). I've found some snippets online but I don't know where and how to use those.
I'd appreciate a lot if somebody could give me detailed informations about how to do this.
Add this toggle method anywhere in your UIViewController. This hides on first tap and shows again in second tap.
- (void)toggleNavBar:(UITapGestureRecognizer *)gesture {
BOOL barsHidden = self.navigationController.navigationBar.hidden;
[self.navigationController setNavigationBarHidden:!barsHidden animated:YES];
}
If there is no navigation controller, link the navigation bar with an IBOutlet and replace with
- (void)toggleNavBar:(UITapGestureRecognizer *)gesture {
BOOL barsHidden = self.navBar.hidden;
self.navBar.hidden = !barsHidden;
}
Then add the following in the method -(void)viewDidLoad {}
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(toggleNavBar:)];
[self.view addGestureRecognizer:gesture];
[gesture release];
If the view where you are going to tap is a UIWebViewController, you have to add the protocol to the view controller and set it as delegate gesture.delegate = self; then add the following:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
This is needed because the UIWebViewController already implements its own gesture recognizers.
Ultimately, you want to send the -setHidden: message to your navigation bar. The easiest way to do this is to make an Outlet and an Action in your in your view controller. Then, in your .xib file, connect the navigation bar to the outlet and some button (even a large, full screen one) to the action.
Outlets and Actions are basic techniques used over and over in iOS
(and Mac) programming, so if you don't understand them, best go read
up on them now. Every beginning iOS/Mac programming book covers this
topic as does Apple's own Getting Started guide (pay particular
attention to the Configuring the View section).
Inside your action, send a message to the outlet like so:
-(void)myButtonAction:(id)sender{
[[self myNavigationBarOutlet] setHidden:YES];
}
This will hide the navigation bar whenever your button is tapped.
(This assumes you have a UINavigationBar in your .xib like you say. These directions will be different if you're working with a UINavigationController that manages its own UINavigationBar)
Related
In IB I've put an View Controller with a Table View and a Navigation bar. Because I want to change the actions (and text) on the buttons when the table is being edited, I decided to create the button programatically.
In the implementation file, I've set up the button (copied from another post on Stackoverflow):
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Title";
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStylePlain target:self action:#selector(EditTable:)];
self.navigationItem.rightBarButtonItem = editButton;
}
But when I run this in the simulator, I don't see the button. Is this the right approach for my goal? Or what am I doing wrong?
Later, I also want to add a Back, Add and Done button.
You probably did not created iboutlet for that navigation bar. Self.navigationItem is a property which is available on any viewcontroller and is applied only if there is a navigationcontroller which manages your viewcontrollers stack. There is no relation to manually created navigationItems..
I assume that either outlet for that navigationbar or going to storyboard, click your viewcontroller and then Editor->Embed In->navigation controller will help you to achieve disered results.
i have an navigation controller in my storyboard, but for one reason i have to make one segue programmatically, but how do i make a push segue programmatically?
this is my code so far:
- (IBAction)nextviewButton:(id)sender {
HolesViewController *Holes = [self.storyboard instantiateViewControllerWithIdentifier:#"HolesViewController"];
Holes.nameString = self.NameField.text;
[self presentViewController:Holes animated:YES completion:nil];
}
Alternatively, I actually prefer to define a segue right in my storyboard, but rather than originating from the button, I have it originate from the view controller itself, e.g.:
Then, give that segue a "storyboard id", say "Details", and then you can invoke that segue programmatically via:
[self performSegueWithIdentifier:#"Details" sender: ...]; // you can specify either the button or `self` for the `sender
I like this because that way, the storyboard continues to visually represent the flow of the app (as opposed to possibly having scenes floating out there with no segues). And you can use the exact same construct for both push and modal segues (and the view controller that's presenting the next view controller doesn't care which one the storyboard uses).
[self.navigationController pushViewController:Holes animated:YES];
Got it
I have a bunch of UIViewControllers subclasses (let's call them MainForm, DetailForm, MoreMinorDetails). Basically the idea is that AppDelegate class instantiates MainForm, user presses some type of button on MainForm and DetailForm comes up. Then on a button on the DetailForm launches MoreMinorDetails. And of course, I should be able to go back down to the MainForm.
Note that there aren't any UINavigationController objects anywhere in sight.
What is the accepted pattern to move between UIViewControllers in a manner described above?
Or am I going about it in the wrong way?
I'll be happy with either XCode or MonoTouch based explanation.
You can use a UINavigationController and hide the navigation bar:
self.navigationController.navigationBar.hidden = YES;
Then in your button's action just push the next view controller:
-(void)buttonAction:(id)sender
{
NextViewController *nextViewController = [[NextViewController alloc] init];
[self.navigationController pushViewController:nextViewController animated:YES];
}
To go back, use
-(void)goBack
{
[self.navigationController popViewControllerAnimated:YES];
}
To go to a certain view controller (you have to know exactly when it was pushed onto the navigation controller's stack):
-(void)goToViewController
{
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
}
Or to pop to your root view controller
[self.navigationController popToRootViewControllerAnimated:YES];
This way, you will obtain the UINavigationController's functionality and keep all the space in the view.
AngryHacker,
My simple suggestion is to follow zoul one. I think the simplest way to achieve what you want it' to create a UINavigationController and use it as a containment controller for other controllers.
So, the way could be create a UINavigationController in the AppDelegate and set it as the rootViewController for your window. When you create a UINavigationController you can pass to it a root controller (in this case MainForm).
In MT it looks like the following (do not trust the code because I've written it by hand)
private UINavigationController navController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
navController = new UINavigationController(new MainForm());
window.RootViewController = navController;
window.MakeKeyAndVisible ();
return true;
}
Now, when you launch the app you will see the MainForm's view and will able to allow navigation among different controllers.
For example, within MainForm you can go to DetailForm like:
this.NavigationController.PushViewController(new DetailForm(), true);
The same applies within DetailForm to MoreMinorDetails.
To go one step back, for example from MoreMinorDetails to DetailForm use
this.NavigationController.PopViewControllerAnimated(false);
To go to the the root controller (MainForm) within DetailForm or MoreMinorDetails use
this.NavigationController.PopToRootViewControllerAnimated(false);
About the space, it's not a problem. I guess you have two ways. The first is to move the bar items you have created within the navigation controller bar. In each controller you can decide what buttons make visible or not. The second is to hide completely the navigation bar and use the button you've already created.
In both ways you can attach actions to these buttons and allow the navigation between controllers. Furthermore, if you choose the first you can also hide the back button for your navigation bar.
A simple note to take in mind is the following:
Since the navigation bar is unique for a UINavigationController, the bar will maintains its state for all the controllers you push in the navigation controller. To explain the concept suppose you have two controllers, say A and B. You first push A and in its ViewWillAppear method you hide a button. When you push B, the button still remains not visible. If you want to unhide the button in B, you can play with its ViewWillAppear method (like before) and so on...
If you don't want to play with UINavigationController you should take a look to new view controller containment functionality provided by UIViewController class. This applies only from iOS >= 5. You can obtain the same effect of UINavigationController mechanism but it could be more difficult to achieve.
Hope that helps.
I have a question on how to add a tap gesture to a UITabBarController. As the UITabBarController already has tap gestures built-in (responding to the tapping of the tab bar items on the tab bar), while technically I can add my own gesture to the tabBarController, the tabBar loses its own native tap gesture. Below is what I am trying to do:
UIViewController *VC1 = ....;
UIViewController *VC2 = ....;
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects: VC1, VC2, nil];
UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc]
initWithTarget:VC1
action:#selector(tap:)];
[tabBarController.view addGestureRecognizer:tapGR];
This correctly responds to the tapping method "tap: ", but the tabBarController loses its native tapping responses to the tap bar items. I tried to add the gesture to one of the view controllers in the tabBarController like this:
[VC1.view addGestureRecognizer:tapGR];
but then doing it this way the tapping gesture is not recognized at all, although the tabBar's native tap recognition of the tapping on the tab bar items is retained.
Does anyone has any suggestions on how to resolve this type of issues? I guess one way is to pick another gesture other than tapping to go with tabBarController, but I'd really rather not do that....
Much thanks for viewing!
I have to wonder what exactly you're trying to do with taps on a control that already handles taps. Do consider whether what you're doing is going to confuse your users.
But if you must, try setting cancelsTouchesInView to NO on the gesture recognizer. That should allow the touches to be passed on to the view in addition to being processed by your recognizer.
I have Uitable view within uiview with navigation bar , I want to add button to the navigation bar to edit the contents of uitableview
any suggestion how to do that please
I think that you want to place your UITableView controller within a UINavigationController (see the UINavigationController class reference for more information).
In your UIViewController for the UITableView, you need to override the methods found under the "Configuring a Navigation Interface" section of the Apple Developer Documentation.
Within this section of methods lies - (UIBarButtonItem *)editButtonItem, which you could override to provide the button for your editing purpose. Under the hood, the UINavigationController will call this method to get the edit button for its user interface. Using this technique ensures that your app stays consistant with the user expierence iOS users have come to love.
There is solution that I tried and worked for me. The solution is
in .h file
UIBarButtonItem *edit;
and set property line as
#property (nonatomic , retain) IBOutlet UIbarButtonItem *edit;
in .m file
in your action handler of the button add
[self.tableView setEditing:TRUE];
Open the .xib file of your view controller and add a UIBarButtonItem either to left or right side of the Navigation Bar and connect the respective IBOutlet to edit button and also the selector method.
Now in the delgate of tableView add the following method
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
//sets the editing style for every row.
return UITableViewCellEditingStyleDelete;
}
Now you can play around with the UITableViewDelegate Methods and also the above methos to get the desired functionality.
Hope it works and do communicate if it does!!