I am trying to call an action (changeMainNumber) in a main view controller from a modal view controller. The action should change the UILabel mainNumber to 2. In ViewController.h, I have:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UILabel *mainNumber;
}
#property (nonatomic, retain) UILabel *mainNumber;
-(IBAction)changeMainNumber;
ViewController.m:
#import "ViewController.h"
#implementation ViewController
#synthesize mainNumber;
- (IBAction)changeMainNumber:(id)sender {
mainNumber.text = #"2";
}
The next view controller is the modal view controller.
ModalViewController.h:
#import <UIKit/UIKit.h>
#class ViewController;
#interface ModalViewController : UIViewController {
}
-(IBAction)callChangeMainNumber:(id)sender;
and ModalViewController.m:
#import "ModalViewController.h"
#implementation ModalViewController
- (IBAction)callChangeMainNumber {
ViewController *viewController = [[ViewController alloc] init];
[viewController changeMainNumber];
}
With this setup the app keeps crashing when callChangeMainNumber is called and I can't figure out what is wrong. Any help you can provide is appreciated!
The code you posted from your ModalViewController is not referencing your ViewController. You are creating a new one in your code. The best solution to your problem would be to make your ViewController a delegate to the ModalViewController.
So in your ModalViewController.h file you should have this code above your #implementation.
#protocol ModalViewControllerDelegate
- (void)shouldChangeMainNumber;
#end
Then in your #implementation of the header have:
#property (nonatomic,assign)IBOutlet id <ModalViewControllerDelegate> delegate;
Now in the .m file where you have your IBAction method, tell the delegate that you want it to change the main number.
- (IBAction)callChangeMainNumber {
[self.delegate shouldChangeMainNumber];
}
Then in your ViewController.m file you need to set yourself as the delegate of the ModalViewController, usually in viewDidLoad is a good place to put it. So create a property in your header for the ModalViewController first and synthesize it, then add this to viewDidLoad.
self.modalViewController.delegate = self;
and finally you need to implement the delegate method in your .m file somewhere
- (void)shouldChangeMainNumber {
mainNumber.text = #"2";
}
Related
It's possible to change an image by clicking on a button inside an other View Controller?
I use this code in order to pass the data from the ViewController to the SecondViewController. I would want to add to the same button the commando to add an image to the SecondViewController... Excused my poor question...
ViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController <SecondViewControllerDelegate> {
IBOutlet UITextField *userNameTextField;
}
#property (nonatomic, strong) UITextField *userNameTextField;
#end
ViewController.m
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"to2"]){
SecondViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
- (void)done:(NSString *)name{
[self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Back in first ViewController, metod Done, with name=%#",name);
userNameTextField.text=name;
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#protocol SecondViewControllerDelegate <NSObject>
-(void) done:(NSString*)someText;
#end
#interface SecondViewController : UIViewController {
IBOutlet UITextField *someText;
IBOutlet UIButton *returnButton;
id delegate;
}
#property (nonatomic, assign) id <SecondViewControllerDelegate> delegate;
#property (nonatomic, strong) UITextField *someText;
- (IBAction)returnButtonPressed:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize someText;
#synthesize delegate = _delegate;
- (IBAction)returnButtonPressed:(id)sender {
[self.delegate done:someText.text];
}
#end
Here is one way that should work for you:
Just set up an NSNotification in your ViewController with the image. Trigger the notification in the other viewController when the button is pressed.
in your image's view controller:
//in ViewDidLoad:
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(changeTheImage) name:#"CHANGE_THE_IMAGE" object:nil];
//then elsewhere in the class:
- (void)changeTheImage {
//change your image here
}
//and in your dealloc, make sure you add this, or it will keep "observing"
[[NSNotificationCenter defaultCenter] removeObserver:self];
Then in the button view controller:
//have this as your button action (or add the line to your button action)
- (IBAction)yourButtonWasPressed:(id)sender {
[[NSNotificationCenter defaultCenter]postNotificationName:#"CHANGE_THE_IMAGE" object:self];
What's the mean to change another UIViewController. because when you click on current UIViewController that's mean the current is on top and visible. what you called another can only be overlap inactive or it's does not exist right now.
So if you want somehow to change the UIImage from another UI, the simplest way is to hold the UIImage or image file name in a global store area such as your AppDelegate class, file. when click change the global area content. and in the ui for image show you can add some code in
- (void)viewWillAppear:(BOOL)animated {
//read and change UIImage content from global store
}
is it what you want ?
I have a UIViewController on a UINavigationStack and from this UIView I load another view not onto the stack but as a subview. This view that I load is just a preferences view for the app that I overlay onto what ever is showing.
i.e.
myViewController <- on the stack button touch loads as a subview to myViewController
+ prefrencesViewController
My question is, is there a way to call a method thats in myViewController from prefrencesViewController? I am trying to use delegates and protocols but its not working, so I am hoping there is either an easy way to do this I don't know about yet or maybe I could get some help with my delegate/protocol...
This is what my code looks like for delegate and protocol set up
//prefrencesViewController.h
#protocol GetPrefrencesViewControllerDelegate <NSObject>
-(void)reloadViewFromSavedPrefrences;
#end
//delegates and protocols
#property (nonatomic, weak) id <GetPrefrencesViewControllerDelegate> delegate;
//prefrencesViewController.m
//delegates and protocols
#synthesize delegate;
//.. inside button action
[[self delegate] reloadViewFromSavedPrefrences];
//myViewController.h
#import "prefrencesViewController.h"
#interface myViewController : UIViewController <UITabBarDelegate, GetGUIEncodedData, GetPrefrencesViewControllerDelegate> {
// prefrencesViewController set up
prefrencesViewController *pvc;
#property (strong, nonatomic) prefrencesViewController *pvc;
//myViewontroller.h
#synthesize pvc;
- (void)viewDidLoad
{
//..
[pvc setDelegate:self];
}
//Delegate and prefrences.. Saved pressed reload the view here.
-(void)reloadViewFromSavedPrefrences {
NSLog(#"WORKED");
}
any help would be greatly appreciated
I'm not sure that you are following the steps that I will present below but if you don't here is the example.
PresentedViewController.h
//import stuff
#protocol PresentedViewControllerDelegate <NSObject>
-(void)methodThatSouldBeImplementedByOtherController; //you can add params
#end
#interface PresentedViewController : UIViewController {
//instance variables
}
#property (nonatomic, assign(week for ARK)) id<PresentedViewControllerDelegate>delegate
//public methods here
PresentedViewController.m
#implementation PresentedViewController
#synthesize delegate;
//method implementation here
-(IBAction)buttonThatWillCallTheDelegate:(id)sender {
if([self.delegate respondsToSelector:#selector(methodThatSouldBeImplementedByOtherController)]) {
[self.delegate methodThatSouldBeImplementedByOtherController];
}
}
ControllerThatWillPresent.h
#interface ControllerThatWillPresent : UIViewController <PresentedViewControllerDelegate> {
//instance variables
}
//some methods maybe
ControllerThatWillPresen.m
#implementation ControllerThatWillPresen
-(void)methodThatWillShowTheVC {
PresentedViewController *vc = [PresentedViewController alloc] init]; //initWithNibname...
vc.delegate = self;
//presentVc, pushVc, addChild ...
}
-(void)methodThatSouldBeImplementedByOtherController {
//do stuff in delegate method
}
Thanks in advance for your help!
In the main ViewController.m of my project I am adding a customized tableView like so:
messageController = [[MyMessagesController alloc] initWithStyle:UITableViewStylePlain];
[self addChildViewController:messageController];
[self.view addSubview:messageController.view];
Then, in the MyMessagesController.m section tableView didSelectRowAtIndexPath: I'd like to write code that would take effect in the ViewController.m where it was created and added as a childViewController.
How can I access the functions of the ViewController.m from MyMessagesController.m?
Can I make it a delegate somehow so I could call [delegate functionName];?
Could I pass information back to the ViewController.m? About which of the rows in table was selected by sending through an NSString or NSArray or anything?
Yes, use a delegate, if you are unsure how best to accomplish this, here is a good reference from Apple about delegate programming
Got it figured out, here's how you turn one viewController into a delegate for another:
In the .h of the parent controller -
#interface ViewController : UIViewController <NameOfDelegate> {
In the .m of the parent controller, once you create the new view -
newViewController.delegate = self;
and also:
- (void)functionToCall:(id)sender {
NSLog(#"Function Called!!!");
}
In the .h of the newViewController you're adding -
#protocol NameOfDelegate;
#interface newViewController : UIViewController/OR/TableViewController {
id <NameOfDelegate> delegate;
}
#property (nonatomic, strong) id <NameOfDelegate> delegate;
#end
#protocol NameOfDelegate
- (void)functionToCall:(id)sender;
#end
in the .m of the newViewController -
#implementation newViewController
#synthesize delegate;
and when you're ready to call the function in your delegate -
[delegate functionToCall:self];
My custom delegate does not receive a call. Here is my setup. ViewController has a SliderView object which is a subclass of UIScrollView:
SlideView.h
#import <UIKit/UIKit.h>
#protocol SlideViewDelegate <NSObject
#required
-(void) didTapImageData:(NSMutableArray*)imageData atIndex:(int)index;
#end
#interface SliderView : UIScrollView<UIGestureRecognizerDelegate> {
__weak id<SlideViewDelegate> slideViewDelegate;
}
#property (nonatomic, weak) id<SlideViewDelegate> slideViewDelegate;
#end
SlideView.m
#import "SliderView.h"
#implementation SliderView
#synthesize slideViewDelegate;
- (void) handleTap:(UITapGestureRecognizer *)recognizer{
NSLog(#"tapped");
[[self slideViewDelegate] didTapImageData: imageData atIndex:0 ];
}
ViewController.h
#interface ViewController : UIViewController <
UIScrollViewDelegate,
SlideViewDelegate>{
SliderView *thumbGalleryView;//delegate and reference are set in XCode
}
ViewController.m
#import "ViewController.h"
#implementation ViewController
-(void)didTapImageData:(NSMutableArray*) imageData atIndex:(int)index{
NSLog(#"NOT WORKING HERE");
}
So ViewController never receives a call at the method above. The thumbGalleryView is linked to ViewController and delegate is set to ViewController too. SlideView's handleTap is printing message fine but [[self slideViewDelegate] didTapImageData: imageData atIndex:0 ]; is ignored. Why?
You have set the delegate which is ivar of scroll view.
You have to set the slideViewDelegate to ViewController
Edited
Add IBOutlet
IBOutlet __weak id<SlideViewDelegate> slideViewDelegate;
Then from your xib connect slideViewDelegate to ViewController
Also remember to change the class of scroll view to SliderView
Added Image for clarity
Double-check where you set your delegate - if your delegate is nil at the time -handleTap: calls your -didTapImageData:atIndex: method, nothing will happen.
i have got two view.
First: FirstViewController
Second: SecondViewController
FirstViewController is my UINavigationController's root controller and inside FirstViewController I ve got UITableView. When a cell is clicked in UITableView, the view is navigated to SecondViewController. Inside SecondViewController i have UILabel. I want to assign this UILabel's value to the cell which is clicked at FirstViewController when Back button is clicked in Navigation Bar. What am i supposed to do to implement this?
I can pass value to SecondViewController from FirstViewController by creating:
SecondViewController *sv;
sv.somestring = someanotherstring;
but can not implement this at SecondViewController to pass the value to a NSString in FirstViewController.
Can u help me please?
Thank you.
ae
The typical way to handle this in the iPhone SDK is to define a delegate protocol. For instance:
#protocol SecondViewControllerDelegate
- (void) viewControllerWillDisappearWithLabelText: (NSString*)text;
#end
Then you would add a delegate property to your SecondViewController, like:
//in the .h file
#interface SecondViewController : UIViewController {
//declare instance variables
}
#property(nonatomic, assign) id<SecondViewControllerDelegate> delegate;
#end
//in the .m file
#implementation SecondViewController
#synthesize delegate;
//[code...]
#end
Then you would update FirstViewController to implement the delegate protocol:
//in the .h file
#interface FirstViewController : UIViewController<SecondViewControllerDelegate> {
//[instance variables]
}
//[methods and properties]
#end
//in the .m file
#implementation FirstViewController
//[code...]
- (void) viewControllerWillDisappearWithLabelText: (NSString*)text {
//do whatever you need to do with the text
}
//[code...]
#end
...and to set the delegate field when FirstViewController creates the SecondViewController:
SecondViewController* sv = [[SecondViewController alloc] init];
sv.somestring = someanotherstring;
sv.delegate = self;
Finally, in SecondViewController you implement viewWillDisappear to be roughly like:
- (void) viewWillDisappear: (bool)animated {
[super viewWillDisappear:animated];
if (self.delegate) {
[self.delegate viewControllerWillDisappearWithLabelText: myLabel.text];
}
}
Ya , there is much a easy way to handle this.....
You can take a Global Variable
In your Delegate.h file declare your variable:
#interface Smoke_ApplicationAppDelegate : NSObject {
UIWindow *window;
UINavigationController *navigationController;
NSString *messageString; //This would be your String Variable
}
#property(nonatomic,retain)NSString *messageString;
Secondly in Delegate.m file
#implementation Smoke_ApplicationAppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize messageString; // Synthesize it over here..
This is Done .Now you can use this String Variable in All/any class you want..
To use this Global Variable.
Just import you Delegate file make the obj of it....
import "DelegateFile.h"
#implementation About
DelegateFile *appDel;
Now in Your class.m
-(void)viewDidLoad { [super viewDidLoad];
appDel=[[UIApplication sharedApplication]delegate];
}
Now you can access it anywhere in your class by this Object:
appDel.messageString
Just follow my Steps Carefully , I am sure this is definitely going to help you.....
Have a easy life,
Declare a string (stringVal)in the appdeleage and set its propert as nonatomic and retain, synthesize it also.In the second view controller you can set the label value to the appdelegate string([appdelegate setStringVal:label.text];) .You can get this value in the first view controller and use it in table(NSString *localString=appdelegate.stringVal];).
All the best.