Switching view controllers from UIToolbar subclass - ios

Please excuse my newness in IOS, but I am trying to switch view controllers when someone clicks on a button in my toolbar. For my toolbar I have overridden the UIToolbar and drawn my own custom toolbar. I have four buttons each with their own action something like this:
NSMutableArray *toolbarItems = [#[] mutableCopy];
[toolbarItems addObject:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"notifications"] style:UIBarButtonItemStyleBordered target:self action:#selector(viewNotifications)]];
I want to be able to do something like:
-(void)viewNotifications
{
NSLog(#"CustomUIToolbar::viewNotifications");
//layoutFlow....
// Show the notifications view controller
NotificationsViewController *rootViewController = [[NotificationsViewController alloc] initWithCollectionViewLayout:layoutFlow];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self presentViewController:navController animated:YES completion:NULL];
}
The problem with this is clearly that the UIToolbar doesn't directly have access to switching view controllers. Is there a way to access the presentViewController method or something like it from within the custom UIToolbar?

Create a protocol and a delegate and let the UIViewController which creates the UIToolBar implement that delegate.
When the user presses a UIBarButtonItem you send the delegate the message (the main UIViewController) and handle the UINavigationController code there.
#protocol ToolBarProtocol <NSObject>
-(void)didPressButton1;
#end
#property (nonatomic) id <ToolBarProtocol> delegate
And when creating your UIToolBar:
YourToolBar *toolbar = [YourToolBar alloc] init];
toolbar.delegate = self;
Inside your method change to tell the delegate what should happen:
-(void)viewNotifications
{
NSLog(#"CustomUIToolbar::viewNotifications");
//layoutFlow....
if ([self.delegate respondsToSelector:#selector(didPressButton1)])
{
[self.delegate didPressButton1];
}
}

Related

UIImagePickerController as Main View Controller of Application and Navigation Controller shown afterwards

My goal is to create an application which features the camera as the first view that appears and then after taking a picture goes to a series of views which are in a navigation controller. The closest existing application to what I want to make is Snapchat.
I've been struggling with this for several days, here's what I have tried (none of these seem to work).
Root View (Inside Navigation Controller) Presents a Modal UIImagePickerController and then segues to next view. [Does not segue]
Same as 1, but dismiss the modal controller then segue. [Kinda Works. Shows the background when loading the UIImagePicker and also when transitioning to the next view]
Use a subclass of UIIMagePickerController as the root view.[Works but does not allow navigation bar to be shown or else crashes on displaying the UIImagePickerController][
Use 3 and don't embed inside a navigation controller (reasoning: since UIImagePickerController is a subclass of navigation controller this should work). [Does not work.]
I've tried about 10 other ways to do the same thing and they fall in this category: [Kinda Works. Most crash or look look ugly].
What is the best way to do this? Any help or advice would be greatly appreciated!
Again if this is confusing, just open snapchat and play with the flow (same flow, totally different idea for the actual app - ie. not a snapchat clone :)
Thanks!
If you present the image picker modally from the navigation controller's root view controller with no animation, then the picker is what you will see first. When you dismiss it, you'll see that root controller, which should be what ever you want to see first when the picker goes away. Is that what you want? This code would be in the root controller:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
static int first = 1;
if (first) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = 0;
[self presentViewController:picker animated:NO completion:nil];
first = 0;
}
}
1st Suggestion:
Make one mainController and add the buttons(depends on how many viewController you have), when button clicked each button will load different viewController.
// appDelegate.h
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) MainViewController *mainController;
//appDelegate.m
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.mainController = [[[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
//each button clicked has following IBAction:
-(IBAction)button1Clicked:(id)sender
{
FirstViewController *firstVC = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:[NSBundle mainBundle]];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:firstVC]autorelease];
[self presentModalViewController:navController animated:NO];
[addVC release];
}
//in FirstViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
self.title = #"xxxx ";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel_Clicked:)]autorelease];
}
-(void) cancel_Clicked:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
Note :
ViewController to be embedded inside a navigation controller, the following code has to be used;
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:firstVC]autorelease];

How to switch views from barbuttonitem?

I have an overlay in which I've created a toolbar containing a done button.
The name of the selector for done button is doneButtonPressed.
Now when I click done button, how do I get a new nib view? Let's us assume I created a nib named TestViewController.
-(void)doneButtonPressed {
//What goes here?
}
If you want to instantiate a UIViewController from a nib you can use the following line of code:
UIViewController *viewControllerName = [[UIViewController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
Then you can present the view modally with:
[self presentModalViewController:(UIViewController *) animated:(BOOL)];
Now if you are using a storyboard, then you could just instantiate a view controller from a storyboard object.
Not sure if this is what you are looking for, but you could turn your view into a "container view". To do that you will need to create subviews and then just switch them out. I did this when I wanted a menu to control a different view.
[self.view insertSubview:(view you want to insert) atIndex:0];
Then when you want to switch it out:
[[[self.view subviews] objectAtIndex:0] removeFromSuperview];
[self.view insertSubview:(view you want to replace with) atIndex:0];
EDITED
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonPressed:)];
- (void)doneButtonPressed {
SkipQViewController *skipQ = [[SkipQViewController alloc] initWithNibName:#"Name" bundle:bundleName];
[self presentModalViewController:skipQ animated:YES];
}
If that does not work try using: SkipQViewController *skipQ = [[SkipQViewController alloc] init]; to instantiate your view controller.
-EDIT-
Instantiate the view controller as such: SkipQViewController *skipQ = (SkipQViewController *)[[UIViewController alloc] initWithNibName:#"sqvc" bundle:nil];

push a view controller from a UIView ios

I have a navigation based application.On click of a button on the navigation bar in the first screen , I am able to push another view controller as follows :
-(void) buttonClicked:(id)sender
{
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
}
Now i have a UIView(separate .h and .m files) as part of the first screen. On click of a button in the UIView, i want to push the SecondViewController.
I have tried the following :
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
It doesnt work!! Kindly help
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
The problem here is that home isn't part of the navigation stack, so [home navigationController] is surely nil. I'm not quite clear on what you're trying to do here, but just creating a view controller doesn't mean that it's actually part of the view controller graph.
Why would it work? Randomly creating view controllers whose view is not even visible, is not the solution. You can either keep a reference to the VC in the view like this:
#imlementation ViewController
- (id) init
{
// ...
aView = [[CustomView alloc] init];
aView.viewController = self;
// ...
}
#end
#interface CustomView
#property (assign) ViewController *viewController;
#end
Or you can search the responder chain at runtime:
UIResponder *next = [view nextResponder];
while (next)
{
if ([next isKindOfClass:[ViewController class]])
{
break;
}
next = [next nextResponder];
}
And now "next" will contain the view controller (or nil if it can't be found).
Try using the same navigationController to push view, this keeps the same stack of ViewControllers.
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
[mv release];
I see your problem now! You need to #import your FirstViewController, then #class it. Then do your push.
So:
//.h
#import "FirstViewContoller.h"
#class FirstViewController;
#interface...
//.m
-(void)return {
FirstViewController *firstview = [[FirstViewController alloc]init(withnibname:)];
[firstView.navigationController pushViewController: firstView.navigationController.topViewController animated: TRUE];
}
If I am not wrong, your UIView though is in separate files, is still added to the screen from a UIViewController class.
Simply, post a notification from UIView to your FirstViewController class where you have access to the navigation controller. Then push the SecondViewController from there.
You Can use this. It Works very well for me:-
Firstly Create Object of AppDelegate in UIView Class and initialize it. Then create Navigationcontroller object in Appdelegate.h :-
#property(strong,nonatomic) UINavigationController *navControl;
In your UIView Class implement this code where you want to push :-
ViewController *objview = [[ViewController alloc]init]; [appDelegate.navControl pushViewController:objview animated:YES];

How can I create a tab view programmatically on iOS

For an iPhone app how can I create a tab view programmatically, preferably in Objective-C?
It's quite simple to create a UITabBar via the UITabBarController. The following example should work within your AppDelegate class.
App Delegate Interface
Firstly, within the interface, we'll define our UITabBarController.
UITabBarController *tabBarController;
App Delegate Implementation
Then, within the implementation file's application:didFinishLaunchingWithOptions: method, we'll then initialise our tab bar controller.
// Initialise our tab bar controller
UITabBarController *tabBarController = [[UITabBarController alloc] init];
Next, you need to create the view controllers that you want to add to the tab bar controller. We'll need to add some information into these to set the tab's title/icon, but I'll come back to that at the end.
// Create your various view controllers
UIViewController *testVC = [[TestViewController alloc] init];
UIViewController *otherVC = [[OtherViewController alloc] init];
UIViewController *configVC = [[ConfigViewController alloc] init];
As the setViewControllers:animated: method requires an array of view controllers, we'll add our view controllers to an array and then release them. (As the NSarray will retain them.)
// Put them in an array
NSArray *viewControllers = [NSArray arrayWithObjects:testVC, otherVC, configVC, nil];
[testVC release];
[otherVC release];
[configVC release];
Then simply provide the UITabBarController with the array of view controllers and add it to our window.
// Attach them to the tab bar controller
[tabBarController setViewControllers:viewControllers animated:NO];
// Put the tabBarController's view on the window.
[window addSubview:[tabBarController view]];
Finally, make sure you call [tabBarController release]; within your dealloc method.
View Controller Implementation
Inside each of your view controllers, you'll also want to set the title and icon for the tab within the init method as follows:
// Create our tab bar item
UITabBarItem *tabBarItem = [self tabBarItem];
UIImage *tabBarImage = [UIImage imageNamed:#"YOUR_IMAGE_NAME.png"];
[tabBarItem setImage:tabBarImage];
[tabBarItem setTitle:#"YOUR TITLE"];
This is how we have to create tabbar programmatically
UINavigationController *BandNavigationController3;
AudienceSettingsViewController *audienceSettingsViewView =[[AudienceSettingsViewController alloc]initWithNibName:#"AudienceSettingsViewController" bundle:nil];
BandNavigationController3 = [[UINavigationController alloc]initWithRootViewController:audienceSettingsViewView];
BandNavigationController3.tabBarItem.title = #"Settings";
BandNavigationController3.tabBarItem.image = [UIImage imageNamed:#"settings.png"];
[BandNavigationController3.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:4];
BandNavigationController3.navigationBar.hidden = YES;
[bandTabBarArray addObject:BandNavigationController3];
[BandNavigationController3 release];
[audienceSettingsViewView release];
[tabBarController setViewControllers:bandTabBarArray];
[bandTabBarArray release];

ipad UIPopoverController with UINavigationController

How can I create a UIPopoverController with integrated UINavigationController so I will be able to slide views inside the UIPopoverController left-right (with navigation bar).
UPDATE:
I open popup like this
- (void)showSettingsViewAtSenderForIPad:(id)sender
{
if (!settingsPopoverController_)
{
SettingsPopoverController *settings = [[SettingsPopoverController alloc] init];
settings.valuesGeneratorOptions = valuesGeneratorOptions_; // setting variables
self.settingsPopoverController_ = [[[UIPopoverController alloc] initWithContentViewController:settings] autorelease];
[settingsPopoverController_ setDelegate:self];
[settingsPopoverController_ setPopoverContentSize:CGSizeMake(320, 480)];
[settings release];
}
if (!infoPopoverController_.popoverVisible)
{
[settingsPopoverController_ presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
}
}
I created a controller which has a NSTableViewController as a root controller in UINavigationController
#interface SettingsPopoverController : UIViewController
{
ValuesGeneratorOptions *valuesGeneratorOptions;
IBOutlet SettingsViewController *settingsViewController;
IBOutlet UINavigationController *navigationController;
}
...
#implementation SettingsPopoverController
...
- (void)viewDidLoad
{
self.settingsViewController.valuesGeneratorOptions = self.valuesGeneratorOptions;
[self.view addSubview:self.navigationController.view];
[super viewDidLoad];
}
...
end
The problem is, that the table is not scrollable inside the popup. It also ignores the table style (initWithStyle not called).
Fix?
SOLUTION:
Found the solution: popOver table view
You create a new nib and a UIViewController. This nib has, as it's top level view, a plain jane UIView and a UINavigationController. The UINavigationController's top UIViewController is whatever view controller you want to display first.
You then display this nib inside your popover controller. In the view did load, you do something like this:
-(void)viewDidLoad
{
[self.view addSubview:self.navigationController.view];
}
This adds your navigation controller's view to your view in your nib, which allows it to be displayed.

Resources