(I've just learn objective-c for a short time. I still don't know how to generate UI elements through writting code now.)
There is one button in .xib.
There is one method in .m.
I want to link these two things by ctrl-click "Touch up Inside" and "File's owner". However, no method shows up when I move the mouse cursor onto File's Owner's icon.
The situation is like this:
http://www.badongo.com/pic/13577347
the .h file:
#import <UIKit/UIKit.h>
#interface ChangeViewController : UIViewController
{
}
-(IBAction)goToSecondView:(id)sender;
-(IBAction)goToCalculatorView:(id)sender;
-(IBAction)test:(id)sender;
#end
the .m file:
#import "ChangeViewController.h"
#import "SecondViewController.h"
#import "CalculatorViewController.h"
#implementation ChangeViewController
-(IBAction)goToSecondView:(id)sender
{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
-(IBAction)goToCalculatorView:(id)sender
{
CalculatorViewController *calculatorViewController =[[CalculatorViewController alloc] initWithNibName:#"CalculatorViewController" bundle:nil];
[self.navigationController pushViewController:calculatorViewController animated:YES];
[calculatorViewController release];
}
Is there anything wrong? Thanks.
Also make sure your File's Owner class is of type 'ChangeViewController'. For doing so, select the File's Owner, Go to the inspector (press command + 4), and set its class to 'ChangeViewController' if not already set.
Please confirm the below points:
1) Have you defined method in .h file?
2) Have you defined method with -(IBAction)
Hope you will be able to bind it.
Cheers.
Double click on file owner's than you will see list of methods you have defined. Connect than method to you control by drag and drop. Once you will attach that method to your button, all the events that can be fired will be displayed. Select TouchUpInside...
link
Related
I'm working on an app and I need to pass data between view controllers. I know this is a common question but I couldn't find an answer for my problem : I'm able to pass data from the FirstViewController (MasterViewController in my case) to the SecondViewController (SettingsViewController) but not the reverse. What happens is that I call a method from the FirstViewController in my SecondViewController.m file. This works and it logs the data. But when I quit the SecondViewController (using [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];) the data is reset.
I tried using other methods to pass data but it didn't work. I'm using this code to pass data:
MasterViewController *vc = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[vc setPorts:SelectedPorts];
I also tried replacing [vc setPorts:SelectedPorts]; with vc.selectedCellIndexes = SelectedPorts; but the same problem occurs.
the setPorts method is declared in the FirstViewController.h file and SelectedPorts is a variable I declared in SecondViewController.m (it's not nil I checked).
Here's the setPorts: in FirstViewController.m :
- (void) setPorts:(id)selectedPorts {
selectedCellIndexes = selectedPorts;
NSLog(#"selectedCellIndexes : %#", selectedCellIndexes);
}
This logs the good value but when I log it in viewWillAppear in FirstViewController.m it's reset to the value it has before I called the method from SecondViewController.m.
Just to clarify, if I DON'T quit the SecondViewController.m, the data isn't reset.
I did read all your comments, and I really thanks you for your help. for convenience, I used a global variable.
Thanks for your help.
You have a list of ports in MasterViewController and you expect to use it in the SettingsViewController.
The MasterViewController can hold this list and SettingsViewController should have an access to it.
In SettingsViewController, have a setSelectedPort method:
#property (nonatomic, retain) id selectedPorts
- (void) setPorts:(id)selectedPorts;
The method saves the selected ports list into a property.
In MasterViewController, call the SettingsViewController and give it the list.
SettingsViewController *vc = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[vc setSelectedPorts:yourValue];
When the list is modified inside the SettingsViewController, the list of ports contained in MasterViewController won't move even if you leave the SettingsViewController.
In secondViewController, You create protocol
#import <UIKit/UIKit.h>
#protocol sampleDelegate <NSObject>
- (void)passValue:(id)selectedPorts
#end
#interface SecondViewController : UIViewController
#property (nonatomic, strong) id <sampleDelegate> passDelegate;
#end
In viewDidLoad or wherever method as per your need, call method like this,
[self.passDelegate passValue:selectedPorts];
In FirstViewController.h,
Import the delegate <sampleDelegate>,
#import "SecondViewController.h"
#interface FirstViewController : UIViewController<SampleDelegate>
#end
In FirstViewController.m,
-(void)passValue:(id)selectedPorts
{
id receivedValues = selectedPorts;
}
and set self in your SecondViewController allocation,
SecondViewController *vc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
vc.passDelegate = self;
There is nothing unusual in the getting result. By doing
MasterViewController *vc = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[vc setPorts:SelectedPorts];
You are creating a new instance of MasterViewController from your SecondViewController. This is not the same from which you navigated to the SecondViewController. So you wont get the expected result. Since you are setting the ports([vc setPorts:SelectedPorts]) to the newly created instance of the Master.
Instead of creating a new instance,just hold the reference of the MasterViewController in SecondViewController in a property and assign it before moving to second VC. As a beginner I suggested this way. But using delegate is the prefferred way passing data back.
Either use delegate methods to communicate with the master VC from the modal VC, or you could do something like this if you want to retrieive some manipulated objects from the modal VC.
Set the object(s) as properties in the modal view controller's .h-file (so they are public).
Using unwind segues, in the master VC, just do this:
-(IBAction)exitModalVC:(UIStoryboardSegue*)segue
{
SomeObject *obj = ((YourModalVC*)segue.sourceViewController).someObject;
//Do what you want with obj
}
EDIT:
This will only work if you are using unwind segue (which is a neat way of dismissing modal VC when using story board)
And you are using this, which is not unwind segues:
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
You were creating a new instance of the first view controller from the 2nd view controller not accessing the same instance of the original caller. That was the reason why while you could see the logs but data were not there when you got back to the original caller - your MasterViewController.
You need to use delegate method. Check my answer for this SO.
This is problem related to object ownership.
Follow the below steps:
As per understanding you want reverse value from "SecondViewController" to "FirstViewController"
Don't create new object of FirstViewController in SecondViewController, it will not work.
Create object of "FirstViewController" in "SecondViewController.h" file.
#property (nonatomic,strong) FirstViewController *firstViewController;
When you navigate from FirstViewController to SecondViewController, please pass the "self".
e.g. SecondViewController *vc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
vc.firstViewController = self;
If you want pass the reverse value to FirstViewController then in SecondViewController.m file.
[self.firstViewController setPorts:SelectedPorts];
And in FirstViewController.m refresh your controls with latest values.
Try above code will defiantly work as per your requirement.
I'm having an issue with the dismissModalViewControllerAnimated method.
The header looks like this:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "GADBannerView.h"
#import "weatherSetUp.h"
#interface weatherPicViewController : UIViewController{
In my viewController.m file I call
-(IBAction)didClickSetting:(id)sender{
weatherSetUp *views = [[weatherSetUp alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:views animated:YES];
}
This all works fine, In my weatherSetUp file once the user has completed set up I was to dismiss the modal view. I do it by calling this method in the above viewController.m file:
-(void)dismissModal{
[self.parentViewController dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:NO];
[self.parentViewController dismissModalViewControllerAnimated:NO];
NSLog(#"Model gone!");
}
But none of these work.
This is the header file of my weatherSetUp file:
#import <UIKit/UIKit.h>
#import "viewController.h"
#interface weatherSetUp : UIViewController
-(IBAction)didClickClose:(id)sender;
#end
And the only method I've implemented is:
-(IBAction)didClickClose:(id)sender{
NSLog(#"CLick ");
viewController *viewEr = [[viewController alloc] init];
[viewEr dismissModal];
}
All the NSLog's work when I click the button, I've searched on here and tried too the above ways of dismissing it and none of them work, any ideas?
What is going wrong is you're calling dismissModal on a random view controller rather than the object that actually has the modal controller. What you'd want to do in didClickClose: is this
[[self parentViewController] dismissModalViewControllerAnimated:NO];
Also, you shouldn't be starting your class names with lowercase characters in Cocoa. They should really be capitalised and have a prefix, eg ABCWeatherSetUp. The prefix can be whatever you want, but generally you want something based on your name, your company's name or your project's name.
insted of [self.parentViewController dismissModalViewControllerAnimated:NO];
write this [self dismissModalViewControllerAnimated:NO];
Your viewEr is not the same viewController which you are trying to close, because you are creating the new object of your viewContoller.
you can create a viewContoller properties and in your viewController class file
weatherSetup.viewController = self.parentViewController;
NOTE: do not use viewContoller as a ivar, use different may name.
I've been trying to switch two views from two separate view controllers for a while and it never works, the simulator always crashes to the home screen. I'm using Xcode 3.2.5 and this is my code -
SwitchViewsViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface SwitchViewsViewController : UIViewController {
}
-(IBAction)pushButton;
#end
SwitchViewsViewController.m
#import "SwitchViewsViewController.h"
#import "SecondViewController.h"
#implementation SwitchViewsViewController
-(IBAction)pushButton {
SecondViewController *screen = [[SecondViewController alloc] initWithNibName:nil bundle:nil
screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:screen animated:YES]
[screen release];
}
SecondViewController.h
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController {
}
-(IBAction)pushBack;
#end
SecondViewController.m
#import "SecondViewController.h"
#implementation SecondViewController
-(IBAction)pushBack{
[self dismissModalViewControllerAnimated:YES];
}
In interface builder, all i've done is linked the file's owner classes and the buttons. Also made the SwitchViewsViewController load first, and not MainWindow. Everything builds but when I try to run the app it crashes and sends it to the home screen. Can anyone help me with this?
When you alloc your secondViewController you init with nib name nil, this should actually be the name of your nib file.
SecondViewController *screen = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
Also, you should close your brackets ;-)
XIB errors are rarely uncovered at compile time. So when you say you made SwitchViewsViewController the starting point of the app, I am assuming that you have altered the main nib file in Info.plist. Usually that nib file is responsible for providing information about the application delegate. So it's a pretty bad idea if you've changed it to SwitchViewsViewController. I suggest you incorporate the MainWindow.xib back. This is easier I think but if you are interested in doing programmatically than take a look at this post.
so i am using presentmodalviewcontroller to change the active views in an ipad app. however when i try to change it using the statement [self presentModalViewController:createCharacter animated:NO]; in an ibaction that is triggered by a button. however i get an error saying expected expression before 'createCharacter'. createCharacter is a custom view controller that i have created... does anyone know what i am doing wrong? if you need any more relevant code just let me know,thanks
additional relevant code:
#import "createCharacter.h";
-(IBAction) buildCharacter{
[self presentModalViewController:createCharacter animated:NO];
}
createCharacter.h :
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface createCharacter : UIViewController {
IBOutlet UIView *view;
}
#end
I'd love to see some code to look at, and without it maybe this advice will be wrong, BUT...in my experience I've always used IBActions with a single argument, and that argument has always been the sender, so something like tying a button press to `
-(IBAction) presentNewController:(id)sender`
where sender is the button that was pressed.
If you use a method like that to detect the button press from IB, then in code what you would want is something like:
// In your current view controller, the target where you wired up the button
-(IBAction) presentNewController:(id)sender
{
if([sender isEqual:<whatever button you expect>])
{
CustomController *con = [[[CustomController alloc] init] autorelease];
[selfpresentModalViewController:con animated:YES];
}
}
You need to allocate and initialise createCharacter before you can push it into the view.
Assuming createCharacter is a view controller:
createCharacter *customView = [[createCharacter alloc] initWithNibName:yourNibNameORnil bundle:yourBundleNameORnil];
[self presentModalViewController:customView animated:YES];
[customView release];
It appears that you are sending a class to presentModalViewController:animated:. You need to initialize the class as Rog showed. As for MahatmaManic's answer, I have no idea why that was getting rid of your error. He is correct for OS X, but the argument is not required for iOS.
There are a few reasons you could still be getting the error after following Rog's example:
You have a variable named createCharacter, which means it was already initialized. In this case, change the name of your class to CreateCharacter. Classes are usually capitalized, and this would ensure that it is not confused with a variable.
The createCharacter header file is not properly imported. If you change the name of the file in XCode, it does not actually change the name of the file. If you try importing the file using the new name, it will not work.
Your initialization code wasn't right. In Rog's example, he used the default argument names. You should change yourNibNameORnil to the name of your NIB file, or nil if you are not using a NIB. You should also change yourBundleNameORnil to nil, assuming the NIB is located in your application's bundle. Here is an example assuming the NIB is in the application and named createCharacter.xib:
createCharacter *customView = [[createCharacter alloc] initWithNibName:#"createCharacter" bundle:nil];
I'm halfway through implementing a very basic 'Add Contact' Button. I am calling the 'Add View' using the code (via a linked UIButton, that works) :
- (IBAction)showAddContact {
NSLog(#"Hit showAddContact");
ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];
addContactNavController = [[UINavigationController alloc] initWithRootViewController:newPersonViewController];
[self presentModalViewController:addContactNavController animated:YES];
}
and then I have also set the delegate resonse of:
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person {
NSLog(#"Hit newPersonViewController");
//ABContact *contact = [ABContact contactWithRecord:person];
[self.navigationController popViewControllerAnimated:YES];
}
in my header I have set:
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#interface test2ViewController : UIViewController <ABNewPersonViewControllerDelegate> {
UINavigationController* addContactNavController;
}
- (IBAction)showAddContact;
#end
I have added the frameworks Addressbook and AddressBookUI.
The add dialog box comes up as expected, I can edit the contact, but I am not able to remove the modal View Controller from the view.
I have even duplicated the problem in a simple test project available here:link text
What am I missing?, I bet it is something extremely simple.
Thanks #norskben
Couple of problems:
You should release the ABNewPersonViewController after presenting it.
You present the ABNewPersonViewController as a modal dialog with presentModalViewController: but you remove it from the screen as if it was pushed on a UINavigationController with popViewControllerAnimated:. Instead you should either push and pop, or present and dismiss. (If you don't know what this means, read a little int he View Controller documentation)
Even though you implement the ABNewPersonViewControllerDelegate protocol, you never set the delegate property of the ABNewPersonViewController.