I'm trying to get my app to go to the next screen. I eneded up creating a simple test app with 2 screens
On the first vue I have a button connected to the following code to call up the next screen
- (IBAction)atest:(id)sender {
if (mHome == nil)
mHome = [[cHome alloc] initWithNibName:#"cHome" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:mHome animated:YES];
}
I put a break point to make sure the code exicutes, it does but..... the next screen does not come up.
complete code
#import <UIKit/UIKit.h>
#interface cHome : UIViewController{
}
- (IBAction)atest:(id)sender;
#end
#interface cHome ()
#end
#implementation cHome
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)atest:(id)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Just like to add onto Unkn0wn and demonstrate how I presented certain views in an app.
Add a storyboard id for your view controller
click on your view controller in your storyboard hierarchy
click the identity inspector
add a storyboard id as a string in the storyboard id box
I then did something like this in my code:
[self presentViewController:[self.storyboard nstantiateViewControllerWithIdentifier:#"Paint"] animated:NO completion:nil];
obviously, your identifier would not be "Paint" but that's what I used. This was my simplist approach, hope it helps good luck!
NOTE: I did not use navigation controllers in my app.
EDIT
would like to point out, that this method kind of makes the controller appear out of nowhere with no animation (I had special animation for my controls as a transition between view controllers so I didn't need to animate the controller itself)
If you want to push a view controller, you can easily create a push segue, from your first view controller to your second view controller, and then push using
[self performSegueWithIdentifier:#"yourSegueIdentifier" sender:self];
"push segues" can be created both via code or in your storyboard file.
You have a mistake in your code:
mHome = [[cHome alloc] initWithNibName:#"cHome" bundle:[NSBundle mainBundle]];
I think it's the nib name. It should be mHome not cHome.
mHome = [[cHome alloc] initWithNibName:#"mHome" bundle:[NSBundle mainBundle]];
You basically cannot push two of the same view controller on one navigation controller.
Related
I want to apply this (https://www.paxxio.in/checkout/onepage/) functionality in my app, I don't have idea that how will I apply this logic. Please see the above url.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Did not understood your question much though, if you want to open a view controller on tableviewCell click you can use tableview delegate method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
inside this method you can load the view controller.
Now loading view controller can be done in many ways.
In case you are using story board and segue:
you can simply call
[self performSegueWithIdentifier:#"your segue identifier" sender:your view controller instance (optional)];
If you are using story board n yet not using segue then you can instantiate a view controller from story board identifier
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"your story board" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#" identifier of view controller you want to load"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
If you are not using story board then instantiate view controller from xib :)
Happy coding buddy :)
I have a view controller called "Help". I placed a label on the view controller story board, but in simulation I couldn't see the label. I used REMenu to put a menu at the top of the view. I can see the menu bar, but I cannot see the label. Here are the files.
#import "Help.h"
#interface Help ()
#end
#implementation Help
#synthesize helpText1;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor whiteColor]];
self.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(handleBack:)];
helpText1.text=#"Hiii";
helpText1.hidden=NO;
// Do any additional setup after loading the view.
}
-(void)handleBack:(id)otherView{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *myVC = (Controller *)[storyboard instantiateViewControllerWithIdentifier:#"QRList"];
[self.navigationController pushViewController:myVC animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Here is the code that calls the "Help" view controller.When we click on the help option in the menu, it will call the "help" view controller.
REMenuItem *helpItem = [[REMenuItem alloc] initWithTitle:#"Help"
subtitle:nil
image:[UIImage imageNamed:#"Ic"]
highlightedImage:nil
action:^(REMenuItem *item) {
NSLog(#"Item: %#", item);
Help *controller = [[Help alloc] init];
[weakSelf setViewControllers:#[controller] animated:NO];
}];
The "Help" view controller is getting called but I couldn't see the label which I dragged on storyboard. I couldn't figure out the issue.
I guess, that your label is being at a wrong view. Probably, your pushed controller doesn't contain the label you put in your nib file. Try to add other objects and see what's happening. If the problem is that I just guessed, then find the exact controller, choose a view and put there the label. Hope you solve that!
Use debug, put breakpoints, to see where you lose label. Check your layouts, maybe...tie your lable to top Space to superView, leading or tralling space to supeView or bottom space to superView. And beginning Xcode 4.4 we don't need synthesize, each added default
I am trying to do a pretty simple thing: support only horizontal orientation in my app, except for 1 stack of view controllers. For simplicity, lets say I have two UIViewControllers. Lets call them maskLandscapeVC and maskAllVC. Each is separately embedded in its own instance of a custom UINavigationController. Here is the code for the navigation controller.
#import "MPTLoginNav.h"
#interface MPTLoginNav ()
#end
#implementation MPTLoginNav
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark
#pragma Interface Orientaiton Methods
- (NSUInteger)supportedInterfaceOrientations
{
if (self.isMaskAllStack)
return UIInterfaceOrientationMaskAll;
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate
{
return YES;
}
#end
On maskLandscapeVC, this code works fine and only the two horizontal orientations can be used.
Users can navigate from maskLandscapeVC to maskAllVC. The following code takes care of that
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:[NSBundle bundleForClass:[self class]]];
self.maskAllVC = [storyboard instantiateViewControllerWithIdentifier:#"maskAllVC"];
[self.navigationController pushViewController:self.maskAllVC animated:YES];
At maskAllVC, the code also works great and all four orientations are supported.
Once on maskAllVC, the user switches to VERTICAL orientation. maskLandscapeVC is a delegate of maskAllVC. While in the vertical orientation on maskAllVC, the user presses some button. The button does a call to the delegate (maskLandscapeVC), based on some conditions, maskLandscapeVC decides to dismiss maskAllVC. It uses the following code
[self.maskAllVC.navigationController popViewControllerAnimated:YES];
[self.maskAllVC.navigationController dismissViewControllerAnimated:YES completion:nil];
Now back on maskLandscapeVC, the orientation is still vertical and of course my view is completely messed up because of it.
I think because you pop it to go back it doesn't really refresh the whole ViewController like it does the first time. Using viewDidLoad instead of viewWillAppear might be the problem. viewDidLoad is only called once.
Do you do a complete layoutSubview refresh if you set breakpoints? Does it call into supportedInterfaceOrientations at all when you pop? What happens if you move your viewDidLoad code to viewWillAppear?
I'm fairly new to Objective-C, programming. The one thing, I'm currently putting up with is passing a value from the first ViewController to the next one.
I've read this entry here and it didn't help me. Which is funny, since his answer has nearly 500 votes, so I must be the problem. What I did was the following.
I opened my PreviewViewController.m and added the following line #import "MainViewController.h" since I wanted to pass a value from the PreviewViewController to the `MainViewController. Then, when I switch the layouts ( which successfully works ) I want to pass a value.
MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
mainViewController.userId = #"539897197";
As you can see, I want to pass the userId. For that, I also created a property in the MainViewController.h
#property ( nonatomic, strong ) NSString *userId;
Now, In my MainViewController.m I want to access the userId. But when I log it, the console tells me it is null. However, when I set the variable right before the NSLog it works, so it seems like the passing is the problem.
Additionally in the MainViewController.m I have the following line
#synthesize userId = _userId;
but even when I removed that line and changed the NSLog to NSLog(#"%#",self.userId); the same problem occurred.
How can I successfully pass the variables? Which step am I doing wrong?
EDIT
This is how I switch the layouts
UIViewController *viewController = [[MainViewController alloc]init];
MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
mainViewController.userId = #"539897197";
[self presentViewController:viewController animated:YES completion:NULL];
Why not create a custom initializer and pass it in that way? Something like
- (id)initWithUserId:(NSString *)aUserId {
self = [super initWithNibName:#"MainViewController" bundle:nil];
if (self) {
self.userId = aUserId
}
return self;
}
Then you can just do:
MainViewController *mvc = [[MainViewController alloc] initWithUserId:#"1234"]
[self presentViewController:mvc animated:YES completion:nil];
If you are using storyboard then you should use prepareForSegue: method to pass data between view controllers. First Create the segue from your PreviewViewController to MainViewController, just control drag from your view controller to next viewcontroller to create segue. Use UINavigationController if you are using push segue. Use this method to segue and pass data
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"yourSegueIndentifier"]){
MainViewController *mvc = (MainViewController *) segue.destinationViewController;
mvc.userId = #"539897197";;
}
}
UIViewController *viewController = [[MainViewController alloc]init];
MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
mainViewController.userId = #"539897197";
[self presentViewController:mainViewController animated:YES completion:NULL];
use mainViewController rather than viewController when presenting the view controller
Here we have two ways for passing data.
First is Custom Delegate
Second is NSNotification
Here we have two view controllers.
ViewController
and
SecondViewController
in SecondViewController
.h
#import <UIKit/UIKit.h>
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text;
#end
#interface SecondViewController : UIViewController
#property (nonatomic, assign)id<SecondViewControllerDelegate> delegate;
#property (nonatomic, strong) IBOutlet UITextField *nameTextField;//It must connect as outlet connection
- (IBAction)doneButtonTapped:(id)sender;
#end
.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
//Either use NSNotification or Delegate
- (IBAction)doneButtonTapped:(id)sender;
{
//Use Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"passingDataFromSecondViewToFirstView" object:self.nameTextField.text];
//OR Custom Delegate
[self.delegate secondViewController:self didEnterText:self.nameTextField.text];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
in ViewController
.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController<SecondViewControllerDelegate>
#property (nonatomic, strong) IBOutlet UILabel *labelName; //You must connect the label with outlet connection
- (IBAction)gotoNextView:(id)sender;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//addObserver here...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFromPreviousViewControllerNotificationReceived:) name:#"passingDataFromSecondViewToFirstView" object:nil];
// Do any additional setup after loading the view, typically from a nib.
}
//addObserver Method here....
- (void)textFromPreviousViewControllerNotificationReceived:(NSNotification *)notification
{
// set text to label...
NSString *string = [notification object];
self.labelName.text = string;
}
- (IBAction)gotoNextView:(id)sender;
{
//If you use storyboard
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
//OR If you use XIB
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.delegate = self;
[self.navigationController pushViewController:secondViewController animated:YES];
}
//Calling custom delegate method
- (void)secondViewController:(SecondViewController *)secondViewController didEnterText:(NSString *)text
{
self.labelName.text = text; //Getting the data and assign the data to label here.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
For your understanding the code I create a simple passing data from one second view controller to first view controller.
First we navigate the view from first view controller to second view controller.
After that we send the data from second view controller to first view controller.
NOTE : You can either use NSNotification or Custom Delegate method for sending data from One View Controller to Other View Controller
If you use NSNotification, you need to set the postNotificationName for getting data in button action method.
Next you need to write addObserver in (sending data to your required View Controller) ViewController and call the addObserver method in same View Controller.
If you use custom delegate,
Usually we go with Custom Protocol Delegate and also we need to Assign the delegate here.
Very importantly we have to set the Custom Delegate Method in the Second View Controller.Because where we send the data to first view controller once we click the done button in second view controller.
Finally we must call the Custom Delegate Method in First View Controller, where we get the data and assign that data to label.Now you can see the passed data using custom delegate.
Likewise you can send the data to other view controller using Custom Delegate Methods
I tried and got the solution for passing the value between viewcontroller.
MainViewController *mainVC = [[self storyboard] instantiateViewControllerWithIdentifier:#"MainViewController"];
mainVC.userId = #"539897197";
[self presentViewController:mainVC animated:YES completion:Nil];
or using this way . You don`t use the storyboard use the following its working fine
MainViewController *mainVC = [[MainViewController alloc] init];
mainVC.userId = #"539897197";
[self presentViewController:mainVC animated:YES completion:Nil];
Please see the image below. Keep in mind I am using xcode 4.5.2 as well. I followed the example on JASidePanels from github Example #2 and I can't seem to get rid of this black box! Otherwise the SidePanel actually works as expected. =)
image of problem
My centerViewController and leftViewController also look the same (code below). But when I tried to do it like the example said to do it, I wasn't having any such luck, so I had to subclass the JASidePanelController:
centerViewController.h:
#import "JASidePanelController.h"
#interface centerViewController : JASidePanelController
#end
centerViewController.m
#import "centerViewController.h"
#interface centerViewController ()
#end
#implementation centerViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Could I very well be missing something? I have commented out a few lines of code to remove the rightViewController on the main JASidePanelController itself, thinking that could be causing a problem and it just caused more issues. I don't have the code for the rightViewController from the example as I am just using the left and center. So I set the code back into its defaults and I am left with a black box over the app in my simulator.
Thanks in advance!
Don't inherit from JASidePanelController for your center view controller. Think of a JASidePanelController as a container view that can hold 3 view controllers. Here is an example from my AppDelegate one of my projects:
self.panelController = [[JASidePanelController alloc] init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *centerViewController = [storyboard instantiateInitialViewController];
self.panelController.centerPanel = centerViewController;
self.panelController.delegate = centerViewController;
self.panelController.rightPanel = [[DBRightViewController alloc] init];
self.panelController.leftPanel = [[DBLeftViewController alloc] init];
Think of it this way, you need a single JASidePanelViewController, which will hold your other view controllers. This can be a subclass of JASidePanelViewController, but it is probably not needed so long as you store the reference to it somewhere. In my example I store the panelController as a property in my AppDelegate.
Then, each of your viewcontrollers will be subclasses of UIViewController.