I have trouble w/ hiding toolbar when leave screen by segue.
Details: App has a few dozen screens, all of them are belonged the same navigation controller. A few screens have toolbar. For these a few screens in -(void)viewDidLoad I use
[self.navigationController setToolbarHidden:NO animated:NO];
and in -(void)viewWillDisappear:(BOOL)animated:
[self.navigationController setToolbarHidden:YES animated:YES];
so toolbar is visible only on necessary screens and the screen which needs toolbar controls the visibility. All work well when I navigate by "back" button.
The trouble starting when I try to navigate by segue like this (goto home & goto another branch).
[owner.navigationController popToRootViewControllerAnimated:NO];
[self performSegueWithIdentifier:SEGUE_NAME sender:self];
toolbar is stay visible in spite of calling -(void)viewWillDisappear which should hide toolbar.
are there any ideas how to perform these "ToolBarHidden" by right way.
thanks
PS: of course I could hide toolbar on every screen, but I want to avoid this unnecessary operations and want to know how to do it right.
**STEP1:** in your controller.h
#interface ViewController : UIViewController {
UIToolbar *bar;
}
#property (nonatomic, strong) IBOutlet UIToolbar *bar;
#end
**STEP2:** in your controller.m
#synthesize bar;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.bar.hidden = NO;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
self.bar.hidden = YES;
}
**STEP3:** connect in Intrface
hope this help you!
Related
I want to design an app with UI like this:
At bottom, I know it is UITabbarController. In each tab, it has many view controllers like BEAT, TOP, FUN... Each tab has different view controllers.
When scroll horizontal, can change from BEAT to TOP to FUN...
How can I design like that? What view controller should I use? It seems like UIPageController in UITabController, but with UIPageController, I don't know how to replace dots at bottom (.) by BEAT, TOP, FUN... at top.
Thanks for your help.
Alternative solution is to add UISwipeGesture(Left/Right) on view and upon swipe action you can push or pop view controllers.
In ViewController.h
#property (retain, nonatomic) UISwipeGestureRecognizer * leftSwipe;
#property (retain, nonatomic) UISwipeGestureRecognizer * rightSwipe;
In ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupSwipeGestures];
}
-(void)setupSwipeGestures
{
_leftSwipe=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(next)];
[_leftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
_rightSwipe =[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(previous)];
[_rightSwipe setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:_leftSwipe];
[self.view addGestureRecognizer:_rightSwipe];
}
- (void) previous
{
// perform pop to get previous viewController
// i.e [self.navigationController popViewControllerAnimated:YES];
}
- (void) next
{
// perform push to get next viewController
// i.e [self.navigationController pushViewController:viewController animated:YES];
}
If you want to use above code in every Controller, then you may define your own viewController and paste above code in it, after that inherit all of your viewControllers where you need above functionality.
You can use XLPagerTabStrip library in each tab of your tab controller. Awesome library, even gives you the swiping feature similar to android which can enable you to swipe through individual page sections as well as keeping tab property.
I'm building an iOS app using a NavigationController. However, in this app I need a sub navigation bar and it needs to be in every view. I initially implemented this using a toolbar in every view. But what happens, when a new view slides in, is that the toolbar slides in as well. I need the toolbar to be persistent, like the navigation bar. What's the best way to approach this?
My best guess is to set [self.navigationController setToolbarHidden:YES animated:YES]; to YES and then somehow positioning that underneath the navbar...
This is how I used to do it in every viewcontroller:
#interface TableViewController ()
#property (weak, nonatomic) IBOutlet UIToolbar *mainToolBar;
#end
#implementation TableViewController
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:YES animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"TV Shows";
[self addRightMenuButton];
[self loadNinjas];
self.mainToolBar.barTintColor = [UIColor whiteColor];
self.mainToolBar.layer.shadowColor = [[UIColor blackColor] CGColor];
self.mainToolBar.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
self.mainToolBar.layer.shadowRadius = 3.0f;
self.mainToolBar.layer.shadowOpacity = 1.0f;
self.tableView.dataSource=self;
self.tableView.delegate=self;
}
Three distinct approaches I can think of trying:
Make a taller Navigation Bar subclass with your secondary toolbar thing at the bottom. Set it as the Navigation Controller's Navigation Bar. I've tried this a couple of times to achieve different things and it didn't work out, but maybe it will for you.
Stick with what you're doing, a second toolbar on every VC, and use a custom VC transition or presentation controller to make it appear like the toolbar isn't moving while the rest of the content is.
Don't do this. I can't really see a way that a double navigation thing is going to be good for an iPhone app.
Very new to iOS development. I'm trying to make an thing that will let me select a photo from the photo library, and display it. I'm using a storyboard with a navigation controller. I'm able to select and display the image just fine, but I can't figure out how to dismiss the imageview and return back to the image picker. I just get a fullscreen image and cant click anywhere to do anything. Code looks like this:
snapViewController.h
#import <UIKit/UIKit.h>
#interface snapViewController : UIViewController <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *ImageView;
- (IBAction) done:(UIStoryboardSegue *)unwindsegue;
#end
My .m
snapViewController.m
#import "snapViewController.h"
#interface snapViewController ()
#end
#implementation snapViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (BOOL)prefersStatusBarHidden {
return YES;
[self setNeedsStatusBarAppearanceUpdate];
}
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if (self.ImageView.image == nil){
UIImagePickerController * imagePickerController = [UIImagePickerController new];
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:NO completion:nil];
}
else {
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
self.ImageView.image = image;
[self.ImageView setUserInteractionEnabled:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction) done:(UIStoryboardSegue *)unwindsegue {
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Storyboard looks like this, I stuck a toolbar on the bottom of the UIImageView with a done button:
Do I need to bind the done button to the [self dismissViewControllerAnimated:YES completion:nil]; action? How can I do this? I've been struggling with this for a couple hours and can't figure it out. Thanks.
Read up a bit on views and windows and view controllers and stuff, came up with this:
- (IBAction)kill:(id)sender {
self.ImageView.image = nil;
[self viewDidAppear:TRUE];
[self dismissViewControllerAnimated:NO completion:nil];
}
I bound my done button to it and it looks like it works. It seems to be acceptable memory wise(opening and closing images multiple times doesn't ever make memory increase over what it was originally). It if this is not the right way to do it please let me know. Thanks.
Modal segues are very special compared to other segues in the sense that when you dismiss the new view controller, you call a method from the old one. The way it works is like this:
In the old view controller create a method of type (IBAction*) with argument (UiStoryBoardSegue*). Example:
-(IBAction*)done:(UIStoryBoardSegue*)segue{}
Then, in the story board, from your "Done" button in the new view controller control-drag to the green (left most) button in the line on the bottom of the new view controller (same view controller as the Done button), the method you created in the old view controller will popup, and you need to select it.
What will happen now is that once the done button is pressed, the modal will dismiss and will call the Done method on the old view controller
You are on the right track with your kill IBAction however there's a few things you don't need in there. You should not be calling viewDidAppear from an action. Let the OS manage all calls to viewDidLoad, willAppear, didAppear, etc.
If you want to remove the imageview's image from displaying, then you simply need to call self.imageView.image = nil;. You could then add another button and hook it up to an action to open the image picker modal and select a different image.
Remember that snapViewController is not a modal, it is simply the root view controller in the navigation stack that happens to have a full-screen image on it. The Navigation controller is a component that holds a bunch of view controllers -- it itself is never displayed to the user. That said, you do not need to dismiss snapViewController to reset the image, you should just need a done or kill action that looks like this:
- (IBAction)kill:(id)sender {
self.imageView.image = nil;
}
Why UISearchBar does not get Focus and keyboard does not appear when UIViewController is pushed to navigation controller for the 2nd time? It seems as no element on the whole view has a focus.
MY USE CASE: I have 2 View Controllers: A and B. Transition is A->B. A, B are pushed to navigation controller.
When I show B for the first time focus is set to the searchbar and keyboard appears.OK.
Then I go back to the A. And again from A->B. Now for the second time there is no focus and keyboard does not appear. It is WRONG.
MY CODE: On the B UIViewController IBOutlet connection to the searchbar is created:
#property (weak, nonatomic) IBOutlet UISearchBar *mySearchBar;
Delegate of the mySearchBar is also set.
I set focus on the searchbar in B UIViewController in viewDidAppear method:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self performSelector:#selector(setCorrectFocus) withObject:NULL afterDelay:0.2];
}
-(void) setCorrectFocus {
[self.mySearchBar becomeFirstResponder];
}
Transitions between controllers are done manually in code like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"myStoryboard" bundle:nil];
AController *a = [storyboard instantiateViewControllerWithIdentifier:#"A"];
[self.navigationController pushViewController:a animated:NO];
Try this
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self setCorrectFocus];
}
-(void)setCorrectFocus
{
[self.mySearchBar becomeFirstResponder];
}
After long searching I found Error. Somewhere in storyboard old connection for UISearchBar with the name mySearchbar was left. Another thing that I had to correct was that the method
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar;
returned NO, every time I went back to previous Controller. But it should return YES to be able to set focus on search bar next time.
Was strugling with the same - had a UISearchBar inside a UITextView's keyboard accessory and even after [self.searchBar becomeFirstResponder] was called, keyboard input was still received by the text view.
This is what finally helped:
[self.searchBar.window makeKeyAndVisible];
Apparently the keyboard accessory is part of a different UIWindow than the UITextField.
Note: To continue typing in the text view, you should then call something like [self.textView.window makeKeyAndVisible]; ...
Have you tried adding self.mySearchBar.delegate = self;
You should use strong in your property
#property (strong, nonatomic) IBOutlet UISearchBar *mySearchBar;
Always set strong in your property for IBOutlet. When you pop B from navigationController, mySearchBar has released, so you push back to B, [self.mySearchBar becomeFirstResponder] is not work.
First, have a look at this screenshot of my storyboard:
It is an application for a sound map. The user can either record a new field recording or chose an existing one from the library and upload them. The ViewController where the user has to add a title/description etc. (or modifies them when coming from the library) is presented modally (on the top right).
If the user choses to cancel this and to delete the recording, he shall return to the recording screen, if he comes from there, otherwiese to the library. If he choses to save/upload the recording, he shall return to the library, where the upload progress will be displayed.
How can I come back to the desired ViewController independently of the ParentViewController that I come from?
I thought about unwindSegue, but that doesn't work for my layout. Then I figured out a dirty workaround where I changed the selected tab of the TabBarController. But then I also want to set up the delegate correctly to pass some data.
Any thoughts are welcome!
I don't think changing the selectedIndex of the tab bar controller is a "dirty workaround" -- that's the way to do it, given your set up. It appears that you would want the EntryViewController (Library) to be the delegate of the EntryDetailViewController. If that's so, you could set up the delegate in the viewDidLoad method of the EntryDetailViewcontroller like this:
#import "DetailViewController.h"
#import "TableController.h"
#interface DetailViewController ()
#property (strong,nonatomic) UITabBarController *tbc;
#end
#implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tbc = (UITabBarController *)self.presentingViewController;
self.delegate = (TableController *)[(UINavigationController *)self.tbc.viewControllers[1] topViewController];
}
- (IBAction)saveAndUpload:(UIButton *)sender {
[self.tbc setSelectedIndex:1];
[self.delegate saveRecording:#"test recording"];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)delete:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
In my example, I just have two buttons to either save or cancel, and my TableController would be the same as your Library controller.