Passing values between views using UISegmentedControl - iphone

I'm trying to pass an integer between two views. When I return from View1 to MainView, the value is not passed and the NSLog(#"Changed map") is not showing in the console. I looked for the answer and tried everything, but it just won't work! Feels like somethings wrong with the delegate...
Any ideas?
View1.h
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
-(void)flipsideViewControllerSelectionChangedToIndex:(int)index;
#end
#interface FlipsideViewController : UIViewController {
}
#property (weak, nonatomic) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UISegmentedControl *mapType;
- (IBAction)valueChangedMap:(id)sender;
#end
View1.m
-(IBAction)valueChangedMap:(id)sender {
[self.delegate flipsideViewControllerSelectionChangedToIndex:[sender selectedSegmentIndex]];
NSLog (#"%d",[sender selectedSegmentIndex]);
[self dismissViewControllerAnimated:YES completion:nil];
}
MainView.h
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate, UIPopoverControllerDelegate, MKMapViewDelegate> {}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property(weak) id<FlipsideViewControllerDelegate> delegate;
#end
MainView.m
-(void)flipsideViewControllerSelectionChangedToIndex:(int)index {
NSLog(#"Changed map");
if (index == 0) mapView.mapType = MKMapTypeStandard;
if (index == 1) mapView.mapType = MKMapTypeHybrid;
if (index == 2) mapView.mapType = MKMapTypeSatellite;
}

You only need an actual delegate property on your view1, and your mainView simply needs to respond to that delegate protocol. Here is what your delegate protocol should look like:
#property(nonatomic,unsafe_unretained) id delegate;
Now in your code when, mainview presents or pushes view1 you need to wire up the delegate like this (pseudo code):
view1.delegate = self;
Also a few nitpicks... you should never have a viewcontroller dismissing itself, mainView should dismiss the view1 when that 'finished' delegate method fires. In addition you should always check that a delegate responds to a selector before firing:
if([self.delegate respondsToSelector:#selector(yourselectorname)]) {
[self.delegate yourselectorname];
}

Related

How to call a method from a UIViewController thats already on the UINavigationController stack

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
}

Trying to dismiss a view controller by tap on cancel using delegation (Not working at all)

Having two view controller within a navigation controller:
PhoneNumbersTVC > holds a list of phone numbers added by NewPhoneNumberTVC
NewPhoneNumberTVC > a controller for adding phone numbers
When I tap on cancel on NewPhoneNumberTVC I like to get back to PhoneNumbersTVC with a delegation as follow.
PhoneNumbersTVC.h
#import <UIKit/UIKit.h>
#import "NewPhoneNumberTVC.h"
#interface PhoneNumbersTVC : UITableViewController <NewPhoneNumberTVCDelegate>
#end
PhoneNumbersTVC.m
- (void)saveBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC
{
NSLog(#"saveBtnWasTappedOnNewPhoneNumberTVC");
[newPhoneNumberTVC.navigationController popViewControllerAnimated:YES];
}
- (void)cancelBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC
{
NSLog(#"cancelBtnWasTappedOnNewPhoneNumberTVC");
[newPhoneNumberTVC.navigationController popViewControllerAnimated:YES];
}
NewPhoneNumberTVC.h
#import <UIKit/UIKit.h>
#class NewPhoneNumberTVC;
#protocol NewPhoneNumberTVCDelegate <NSObject>
- (void)saveBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC;
- (void)cancelBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC;
#end
#interface NewPhoneNumberTVC : UITableViewController
#property (weak, nonatomic) id <NewPhoneNumberTVCDelegate> delegate;
#property (strong, nonatomic) NSManagedObjectContext *managedOC;
#property (weak, nonatomic) IBOutlet UITextField *phoneNumberTextField;
- (IBAction)saveBtnTapped:(UIBarButtonItem *)sender;
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender;
#end
NewPhoneNumberTVC.m
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender
{
NSLog(#"cancelBtnTapped");
self.phoneNumberTextField.text = #"";
self.phoneKindTextField.text = #"";
[self.delegate cancelBtnWasTappedOnNewPhoneNumberTVC:self];
}
When I tap on cancel on NewPhoneNumberTVC I see that above method cancelBtnTapped fires but delegation does not work, no method executes in PhoneNumbersTVC. View doesn't go away and I don't see: cancelBtnWasTappedOnNewPhoneNumberTVC on console.
If you want this method cancelBtnWasTappedOnNewPhoneNumberTVC: get called, you definitely need to set the delegate of your NewPhoneNumberTVC object to a PhoneNumbersTVC object. For example, there should be existing some codes in PhoneNumbersTVC.m :
NewPhoneNumberTVC *myNewPhoneNumberTVC = [[NewPhoneNumberTVC alloc] init];
myNewPhoneNumberTVC.delegate = self;
You can log as following to verify that the delegate is set successfully or not"
NewPhoneNumberTVC.m
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender
{
NSLog(#"cancelBtnTapped");
self.phoneNumberTextField.text = #"";
self.phoneKindTextField.text = #"";
NSLog(#"self.delegate :%#",self.delegate);
[self.delegate cancelBtnWasTappedOnNewPhoneNumberTVC:self];
}

Using delegate to pass data between views

I am building a utility application which shares data between main view and flip view. Actually, it is not exactly the flip view that's holding data, it's the custom view that's an instance of the flip view when it gets loaded. I have explained the specifics in my previous thread here, but I haven't got a solution yet. And I have redeveloped my code, hopefully this time I could make myself clear.
The general concept here is I create and store data in my main view, and pass it to the flip side view using the predefined delegate in the FlipViewController. Then in the FlipViewController, I store the data in my own delegate and pass it to the custom view which implements my own delegate method. The following is the main portions of the code.
MainViewController.m (only adopts <FlipsideViewControllerDelegate> protocol)
- (IBAction)showInfo:(id)sender {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.chart = data;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
FlipsideViewController.h
#protocol FlipsideViewControllerDelegate;
#protocol ChartDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
id <ChartDelegate> delegate2;
DataModel *chart;
}
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic, assign) id <ChartDelegate> delegate2;
#property (nonatomic, retain) DataModel *chart;
- (IBAction)done:(id)sender;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#protocol ChartDelegate <NSObject>
- (void)getParams:(DataModel *)dataModel;
#end
FlipsideViewController.m
#synthesize delegate, delegate2;
#synthesize chart;
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
if ([delegate2 respondsToSelector:#selector(getParams:)]) {
[delegate2 getParams:chart];
}
}
customDrawing.h
#interface customDrawing : UIView <ChartDelegate>{
DataModel *chartData;
}
#property (nonatomic, retain) DataModel *chartData;
#end
customDrawing.m
#synthesize chartData;
-(void)getParams:(DataModel *)dataModel{
chartData = dataModel;
}
It turns out the data didn't get passed to the chartData object in my custom view. HELP?
You are missing the fundamentals. I do not think you need delegates to achieve this task but here we go.
A protocol is like a contract. In you FlipsideViewController class you defined the protocol which essentially states if you conform to this protocol then you must implement this method.
How do you conform to a protocol?
In MainViewController the #interface will look something like this
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
The fact that you have the protocol written in angled brackets means that you promise to conform to the protocol and therefore have to implement
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
in your MainViewController.m.
Now when MainNavigationController set's itself as the delegate (controller.delegate = self;) it finishes the link. This allows the FlipsideViewController to call
[delegate flipsideViewControllerDidFinish:self];
Which will call the method defined in MainViewController which dismisses the modal view controller.
You have defined a second protocol (you could have added the method to the first and then you would not have to adopt two protocols) and as others have pointed out you have not linked the classes up by doing
controller.delegate2 = self;
This would not solve your problem. You would still need to conform to the ChartDelegate by adding it to the declaration. Once you have done that you will still not be out of the water because the method is not correct.
Full solution - not using delegates as they are not really required here
MainViewController.h
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
- (IBAction)showInfo:(id)sender;
#end
MainViewController.m
#implementation MainViewController
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
/*
* The labelText property is defined in the header for FlipsideViewController
* In this case this is the easiest way to get data from this controller to
* the controller we are about to display
*/
controller.labelText = #"WHAT EVER YOU WANT TO SEND"; // <---- sending data
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
FlipsideViewController.h
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController
/*
* These properties have been added. The label is used for displaying the text
* and needs to be hooked up in Interface builder
*
* The NSString is the property that is holding the data passed from MainViewController
*/
#property (nonatomic, retain) IBOutlet UILabel *testLabel;
#property (nonatomic, copy) NSString *labelText; from MainViewControlller
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
FlipsideViewController.m
#implementation FlipsideViewController
#synthesize delegate = _delegate;
/*
* We need to synthesise out properties so we get our getters and setters created
*/
#synthesize testLabel = _testLabel;
#synthesize labelText = _labelText;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
/*
* This is called once the view is set up and all connections have been made in
* interface builder. Therefore we can now set the text of our test label
*/
self.testLabel.text = labelText;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
- (void)dealloc
{
/*
* Memory management for the ivars we added
*/
[_testLabel release];
[_labelText release];
[super dealloc];
}
#end
You have two properties: delegate and delegate2. You are assigning a value to delegate, but calling the method on delegate2 later.
You need to assign the delegate2 (your customDrawing class). You are only assigning the delegate.

Passing UISegmentedControl values from FlipSideViewController in an Utility application to the mainviewcontroller…

For example, I want the maptype in the Mainviewcontroller to change from satellite to hybrid if the segmentedcontrol in the flipsideviewcontroller changes? What am i doing wrong? Basically, I want the mainviewcontroller to react to the changes made in the flipsideviewcontroller!!!
FlipsideViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKMapView.h>
#protocol FlipsideViewControllerDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
IBOutlet UISegmentedControl *mapType_;
}
#property (nonatomic, retain) UISegmentedControl *mapType_;
#end
MainViewController.h
#interface MainViewController : UIViewController <XXXX> {
IBOutlet UISegmentedControl *mapType;
}
#property (nonatomic, retain) UISegmentedControl *mapType;
#end
MainViewController.m
-(void)viewDidLoad {
if(mapType.selectedSegmentIndex==0){
mapView.mapType=MKMapTypeStandard;
}
else if (mapType.selectedSegmentIndex==1){
mapView.mapType=MKMapTypeSatellite;
}
else if (mapType.selectedSegmentIndex==2) {
mapView.mapType = MKMapTypeHybrid;
}
}
Any ideas of how to make this possible? What am i doing wrong? Would really appreciate an answer! Thanks!
How do I implement the delegate method (as phix23 answered)...?
(1) Extend theFlipsideViewControllerDelegateprotocol by this new method:
-(void)flipsideViewControllerSelectionChangedToIndex:(int)index;
(2) Add an IBAction in FlipsideViewController in order to resond to the ValueChanged-Event of the segmented control:
-(IBAction) valueChanged {
[delegate flipsideViewControllerSelectionChangedToIndex: mapType_.selectedSegmentIndex];
}
(3) In MainViewController implement the delegate method:
-(void)flipsideViewControllerSelectionChangedToIndex:(int)index {
if (index == 0) mapView.mapType = MKMapTypeStandard;
if (index == 1) mapView.mapType = MKMapTypeSatellite;
if (index == 2) mapView.mapType = MKMapTypeHybrid;
}
And delete the IBOutlet in MainViewController!

Implementing delegate methods for modal view controller data transfer

I have a simple project to present a modal view controller and transfer back a string based on which button in the modal VC that gets pressed. I based it all on watching the Stanford class on iTunes U. It looks like I have everything correct, but I get a couple of compiler warnings.
First I get one called passing argument 1 of 'setDelegate:' from incompatible pointer type in TransferViewController.m
Second I get four warnings called Invalid receiver type 'id <MyModalViewControllerDelegate>*' but these aren't displayed in the build results area, rather next to the offending lines in MyModalViewController.m, both lines in each of the button actions.
Here's the code...
// TransferViewController.h
#import <UIKit/UIKit.h>
#import "MyModalViewController.h";
#interface TransferViewController : UIViewController <MyModalViewControllerDelegate> {
UILabel *label;
UIButton *button;
}
#property (nonatomic, retain) IBOutlet UILabel *label;
#property (nonatomic, retain) UIButton *button;
- (IBAction)updateText;
#end
// TransferViewController.m
#import "TransferViewController.h"
#implementation TransferViewController
#synthesize label;
#synthesize button;
- (IBAction)updateText {
MyModalViewController *myModalViewController = [[MyModalViewController alloc] init];
myModalViewController.delegate = self; // I get the warning here.
[self presentModalViewController:myModalViewController animated:YES];
[myModalViewController release];
}
- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog {
label.text = selectedDog;
[self dismissModalViewControllerAnimated:YES];
}
#end
// MyModalViewController.h
#import <UIKit/UIKit.h>
#protocol MyModalViewControllerDelegate;
#interface MyModalViewController : UIViewController {
UIButton *abby;
UIButton *zion;
id <MyModalViewControllerDelegate> delegate;
}
#property (assign) id <MyModalViewControllerDelegate> delegate;
- (IBAction)selectedAbby;
- (IBAction)selectedZion;
#end
#protocol MyModalViewControllerDelegate <NSObject>
#optional
- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog;
#end
// MyModalViewController.m
#import "MyModalViewController.h"
#implementation MyModalViewController
#synthesize delegate;
- (IBAction)selectedAbby {
if ([self.delegate respondsToSelector:#selector (myModalViewController:didFinishSelecting:)]) {
[self.delegate myModalViewController:self didFinishSelecting:#"Abby"];
}
}
- (IBAction)selectedZion {
if ([self.delegate respondsToSelector:#selector (myModalViewController:didFinishSelecting:)]) {
[self.delegate myModalViewController:self didFinishSelecting:#"Zion"];
}
}
Get rid of those *s after id <something> and before delegate.
So make this
id <MyModalViewControllerDelegate> *delegate;
this
id <MyModalViewControllerDelegate> delegate;