before asking this question, I did some research of course. One of the links or topics I have found on google and on stackoverflow is this:
How do I load another view controller from the current view controller's implementation file?
In my case, I have two viewcontrollers in my project, namely:
ViewController (ViewController.h and ViewController.m) - my main vc
LeftViewController (LeftViewController.h and LeftViewController.m) - my second vc. It will be loaded upon clicking a button from my main vc.
Please take note that it is my 3rd day in my job, self training, and I find objective-c quite hard compared to others, like C# ... Oh I miss C#.
Going on, I tried following the steps from the links that I've got as well as the link I gave at the top.
Here are my codes:
a. Inside my ViewDidLoad in my ViewController.m
// add navigation button left
UIButton *leftNavigationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[leftNavigationButton setFrame:CGRectMake(10, 65, 30, 20)];
[leftNavigationButton setTitle:#"<" forState:UIControlStateNormal];
[leftNavigationButton addTarget:self action:#selector(navigateLeft) forControlEvents:UIControlEventTouchUpInside];
[leftNavigationButton.layer setBorderWidth:1.0f];
[leftNavigationButton.layer setBorderColor:[[UIColor whiteColor] CGColor]];
[leftNavigationButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.view addSubview:leftNavigationButton];
b. the method inside my ViewController.m (of course outside the ViewDidLoad:
- (void)navigateLeft
{
// LeftViewController *leftViewController = [[LeftViewController alloc] init];
// [leftViewController viewDidLoad];
_leftViewController = [[LeftViewController alloc] initWithNibName:#"UI For LeftButton" bundle:nil];
[self.ViewController: self.leftViewController animated:YES completion:nil]; //Error in this line, spefically in self.ViewController<---
}
c. ViewController.h
//
// ViewController.h
// Navigation_Task
//
// Created by Glenn on 9/4/15.
// Copyright (c) 2015 Ayi. All rights reserved.
//
#import <UIKit/UIKit.h>
// for LeftViewController
#class LeftViewController;
#interface ViewController : UIViewController
#property (nonatomic, retain) NSMutableString *resultText;
// for LeftViewController
#property (strong, nonatomic)LeftViewController *leftViewController;
#end
and lastly, (this is not included in the link above), my code for loading the LeftViewController.
a. viewDidLoad in LeftViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
LeftViewController *leftViewController = [[LeftViewController alloc] initWithNibName:nil bundle:nil];
// set background and title of the view
[leftViewController.view setBackgroundColor:RGB(19,181,234)];
leftViewController.title = #"Left View Controller";
[self.navigationController pushViewController:leftViewController animated:YES];
}
Sorry if this question is too long, I can't shoot my questions to the developers here in the office, because I'm shy and they don't wanna be bothered :(
You are using right Controller for navigation i.e. UINavigationController, but to make it navigate I will recommend you to use storyboards. Take your UINavigationController as a rootviewcontroller and further take any UIViewController as its rootviewcontroller and then on 2nd UIViewController to navigate attach a Segue to it and provide it a identifier let say "PushToSecond" and in your buttons Method do the following:
(void)navigateLeft
{
[self performSegueWithIdentifier:#"PushToSecond" sender:self];
}
hope this would help
I suggest you take a look into Apple's documentation on UINavigation.
documentation
You can either add as many viewController objects into the navigation stack as needed or present it incase you need to show it temporarily.
I would like to answer my own question.
I have two buttons in my main ViewController.
1 button for LeftViewController
1 button for RightViewController.
Meaning I need to display each new viewcontroller or screen when I click 1 of those buttons.
Here are my codes:
Just inside the event handler (is my term correct? I'm from windows) of the two buttons, put the following:
Code for 'Left Screen/View Controller'
- (void)navigateLeft
{
// LeftViewController *leftViewController = [[LeftViewController alloc] init];
// [leftViewController viewDidLoad];
// _leftViewController = [[LeftViewController alloc] initWithNibName:#"UI For LeftButton" bundle:nil];
LeftViewController *leftViewController = [[LeftViewController alloc] initWithNibName:nil bundle:nil];
// set background and title of the view
[leftViewController.view setBackgroundColor:RGB(19,181,234)];
leftViewController.title = #"Left View Controller";
[self.navigationController pushViewController:leftViewController animated:YES];}
Similarly, I need to put the same type of codes (just renaming the leftViewController into RightViewController)
- (void)navigateRight
{
RightViewController *rightViewController = [[RightViewController alloc] initWithNibName:nil bundle:nil];
// set background and title of the view
[rightViewController.view setBackgroundColor:RGB(19,181,234)];
rightViewController.title = #"Right View Controller";
[self.navigationController pushViewController:rightViewController animated:YES];
}
Now I can push any of the two button and will display a new ViewController (or screen).
Related
I'm trying to transition our app to use SWRevealViewController to give us a side-bar on each side of the application. But despite following the code in one of the example apps, I'm getting an error where the ViewController for the front view doesn't work properly. viewDidLoad gets called, but everything remains black.
Interestingly, if in my viewDidLoad, I set the background colour to red of the view, this is reflected. But stuff in Interface builder from the original story board is not.
The code I use in the AppDelegate is:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
MainViewController *frontViewController = [[MainViewController alloc] init];
RearViewController *rearViewController = [[RearViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
UINavigationController *rearNavigationController = [[UINavigationController alloc] initWithRootViewController:rearViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:rearNavigationController frontViewController:frontNavigationController];
revealController.delegate = self;
RightViewController *rightViewController = rightViewController = [[RightViewController alloc] init];
rightViewController.view.backgroundColor = [UIColor greenColor];
revealController.rightViewController = rightViewController;
//revealController.bounceBackOnOverdraw=NO;
//revealController.stableDragOnOverdraw=YES;
self.viewController = revealController;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark - SWRevealViewDelegate
- (id <UIViewControllerAnimatedTransitioning>)revealController:(SWRevealViewController *)revealController animationControllerForOperation:(SWRevealControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if ( operation != SWRevealControllerOperationReplaceRightController )
return nil;
if ( [toVC isKindOfClass:[RightViewController class]] )
{
if ( [(RightViewController*)toVC wantsCustomAnimation] )
{
id<UIViewControllerAnimatedTransitioning> animationController = [[CustomAnimationController alloc] init];
return animationController;
}
}
return nil;
}
This is the Main.Storyboard which is just for the MainViewController:
When the app loads, the view is just black. But I can drag from both the left and right edge and view the side bars as would be expected. So it's only the FrontView that is coming up black. I stuck an NSLog() into the ViewDidLoad, which appears in the console, as does one in -(void)loadView{}, which shows the View is loading.
If I put into the viewDidLoad a [self.view setBackgroundColor:[UIColor redColor]] this takes effect, meaning it is linked to the view, but it's just the view inside the storyboard is not appearing. Which is weird since the Storyboard also contains a NavigationController, which does appear (I think - unless that navigation controller is coming from somewhere else - which I'm pretty sure it isn't).
Any thoughts on what might be causing this?
I had the same thing going on. I fixed it while looking on the Example code.
In your Storyboard add a UIViewController
Select it and in Identity Inspector just use 'SWRevealViewController' as class
Add a UITableViewController to your story board
Now select your previously added ViewControler and right-click-draw a line to your TableViewController
Select 'reveal view controller set controller'
Click on the newly added Segue and in Attribute Inspector change the identifier to 'sw_rear'
Add any custom ViewController (for example 'MyViewController') to the story board
Select it, then go to the Menu->Editor->Embed In->Navigation Controller
Now a new Navigation Controller should appear
Again right-click-draw a line from the first ViewController to your new NavigationController
Again choose 'reveal view controller set controller'
Now set the identifier of this new Segue to 'sw_front'
Now you have a Basic Setup and when running your app, you should see your custom ViewController. Now the Button for the Menu has to be added.
In your ViewControllers .m add following:
#interface MyViewController ()
#property (nonatomic) IBOutlet UIBarButtonItem* revealButtonItem;
#end
- (void)viewDidLoad {
[super viewDidLoad];
[self customSetup];
}
- (void)customSetup
{
SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
[self.revealButtonItem setTarget: self.revealViewController];
[self.revealButtonItem setAction: #selector( revealToggle: )];
[self.navigationController.navigationBar addGestureRecognizer: self.revealViewController.panGestureRecognizer];
}
}
Now again switch to the story board. Add a UIBarButtonItem to MyViewController. Again right-click-draw a line from MyViewController to this new item in the NavigationBar. Choose 'revealButtonItem'.
Thats it! Repeat the last steps for every ViewController you want to add. You only have to connect them with right-click-drawing from the TableView to your newly added NavigationController of each of your added ViewControllers. To push the ViewControllers just select 'reveal view controller push controller'.
Hope that helps a bit!
I need popover view. i followed this instructions.
Init: Create two UIViewController in storyboard.
lets say FirstViewController which is normal and SecondViewController Which we make Popup.
Model Segue: Put UIButton In FirstViewController and create a segue on this UIButton to SecondViewController as model segue.
Make Transparent: Now selet UIView (UIView Which is created by default with UIViewController) of SecondViewController and change its background color to clear color.
Make background Dim: Add a UIImageView in SecondViewController which cover hole screen and sets its image to some dimmed semi transparent image. You can get a sample from here : UIAlertView Background Image
Display Design: Now Add a UIView and make and kind of design you want to show. Here I have shown screen shot of my storyboard.
Here I have add segue on login button which open SecondViewController as popup to ask username and password
Important: Now that main step. We want that SecondViewController dont hide FirstViewController completely. We have set clear color but this is not enough. By default it add black behind model presentation So we have to add one line of code in viewDidLoad of FirstViewController. You can add it at other place also but it should run before segue.
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
Dismiss: When to dismiss is depend on you. This is a model presentation so to dismiss we do what we do for model presentation:
[self dismissViewControllerAnimated:YES completion:Nil];
But am USING NAVIGATION CONTROLLER,, for that transparent background is not coming?????
Kindly help me..!!!! My screen shot is below.
create one view controller in freeform mode just like following image
in your first view controller add the one UIButton just like the following image
in your first view controller.h add the following line
#import "UIPopoverController+iPhone.h"
#interface first view controller : UIViewController<UIPopoverControllerDelegate>
#property (nonatomic,strong) UIPopoverController *popOver;
#property (strong, nonatomic) IBOutlet UIButton *popbtn;
in your first view controller.m add the following line to the button action method
- (IBAction)popButton:(UIButton *)sender
{
UILabel *showlblView=[[UILabel alloc]init];
showlblView.frame=CGRectMake(10, 10, 250, 40);
showlblView.text=#"Gopi";
showlblView.textColor=[UIColor whiteColor];
showlblView.textAlignment=NSTextAlignmentCenter;
final *vc=[[final alloc] init];
[vc.view addSubview:showlblView];
self.popOver=[[UIPopoverController alloc]initWithContentViewController:vc];
[self.popOver setPopoverContentSize:CGSizeMake(300, 200)];
CGRect popoverframe=CGRectMake(self.popbtn.frame.origin.x, self.popbtn.frame.origin.y, self.popbtn.frame.size.width, self.popbtn.frame.size.height);
[self.popOver presentPopoverFromRect:popoverframe inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
here ur NSObjet class file UIPopoverController+iPhone.h
.h file
#import <UIKit/UIKit.h>
#interface UIPopoverController (iPhone)
+ (BOOL)_popoversDisabled;
#end
.m file
#import "UIPopoverController+iPhone.h"
#implementation UIPopoverController (iPhone)
+ (BOOL)_popoversDisabled {
return NO;
}
#end
the full project code is available at the following link :
https://www.sendspace.com/file/ktie4t
i had the same problem and didn't find solution how to solve it with segue on storyboard, but programmatically it's work fine, when i presenting second controller on first controller (that pushed with navigationViewController). if it's not critical for you, try this:
+ (void)showWithParent:(UIViewController *)parentController {
static SomeViewController *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
singleton = [storyboard instantiateViewControllerWithIdentifier:#"SomeViewControllerID"];
});
[parentController presentViewController:singleton animated:YES completion:nil];
}
or just:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *secondController = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID"];
[firstController presentViewController:secondController animated:YES completion:nil];
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];
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 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.