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

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!

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
}

Passing values between views using UISegmentedControl

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];
}

Issue with UIButton Subclass delegate method

Here is the situation. I have a view controller titled "MyViewController." Within this view controller I have a text editing feature that uses subclassed buttons. The name of the UIButton Subclass is "ColorSwatch"
I have setup delegate/protocol methods in the "ColorSwatch.h" subclass as follow.
// ColorSwatch.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#protocol ColorSwatchDelegate <NSObject>
- (void)fontColor:(UIColor *)color;
#end
#interface ColorSwatch : UIButton {
id <ColorSwatchDelegate> colorSwatchDelegate;
CAGradientLayer *gradient;
UIView *currentView;
UIColor *fontColor;
}
#property (nonatomic, retain) id <ColorSwatchDelegate> colorSwatchDelegate;
#property (nonatomic, retain) CAGradientLayer *gradient;
#property (nonatomic, retain) UIView *currentView;
#property (nonatomic, retain) UIColor *fontColor;
#end
Now in my "ColorSwatch.m" I have:
// ColorSwatch.m
#import "ColorSwatch.h"
#import <QuartzCore/QuartzCore.h>
#import "MyViewController.h"
#implementation ColorSwatch
#synthesize gradient;
#synthesize currentView;
#synthesize colorSwatchDelegate;
#synthesize fontColor;
-(void)setupView{
"Makes the subclassed buttons pretty"
}
-(id)initWithFrame:(CGRect)frame{
if((self = [super initWithFrame:frame])){
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if((self = [super initWithCoder:aDecoder])){
[self setupView];
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
}
return self;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self magnify:view];
fontColor = view.backgroundColor;
[self.colorSwatchDelegate fontColor:fontColor];
}
- (void)magnify:(UIView *)view
{
}
- (void)dealloc
{
[currentView release];
[gradient release];
[fontColor release];
[super dealloc];
}
#end
In the "MyViewController.h" I have:
// MyViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "ColorSwatch.h"
#interface MyViewController : UIViewController <ColorSwatchDelegate> {
UITextField *photoLabelTextField;
}
#property (nonatomic, retain) IBOutlet UITextField *photoLabelTextField;
#end
In the "MyViewController.m" I have:
- (void)fontColor:(UIColor *)color
{
NSLog(#"Selected Font Color");
[self.photoLabelTextField setTextColor:color];
}
Now the delegate method sort of works, meaning when I tap on a color button the
NSLog(#"Selected Font Color");
message gets fired. But the problem is that I cannot change the
[self.photoLabelTextField setTextColor:color];
property. I have tried numerous ways of changing the property, the only thing that I can do is send NSLogs, anything I try to change a property in the "MyViewController" Class nothing happens.
If anyone could please help me out, I would appreciate it.
Thank you
The problem is that the ColorSwatch is sending delegate messages to a dangling instance of MyViewController that it incorrectly allocated in it's initWithCoder: method.
UIControls shouldn't allocate ViewControllers to be their delegates... it goes the other way around.
Delete these lines...
// in ColorSwatch.m initWithCoder:
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
Then, in MyViewController.m ...
- (void)viewDidLoad {
ColorSwatch *colorSwatchButton = [[ColorSwatch alloc] buttonWithType:UIButtonTypeCustom];
// or place a ColorSwatch in the xib, on MyViewController's view... But not before you
// you delete lines from initWithCoder, otherwise it's infinite circular allocation
colorSwatchButton.frame = CGRectMake(/* ... */);
colorSwatchButton addTarget:self action:#selector(csButtonPressed:) forControlEvent: UIControlEventTouchUpInside];
// and so on...
// now the important part:
colorSwatchButton.colorSwatchDelegate = self;
// see - the ViewController is in charge of allocation, sets itself up as the delegate
[self.view addSubview:colorSwatchButton];
}
Instead of building the button in code, you can use IB.
Step 1: make the delegate an outlet...
#property (nonatomic, retain) IBOutlet id <ColorSwatchDelegate> colorSwatchDelegate;
Step 2: draw the buttons in IB, and set their class to ColorSwatch.
Then you can skip the code I wrote in viewDidLoad.
Step 3: The newly placed button should now present an outlet in IB. You can drag from that to the MyViewController as you normally do.
There might be a connection problem in your IBOutlet photoLabelTextField, you may have forgotten to connect xib text field with your photoLabelTextField

Sharing Data between XIB's

I'm following the James Brannan tutorial's, and im trying to share data between some xbis. No luck.
I have 2 xib's. The first, simple button and textfield. The second, just a label, to show the result of the first xib textfield.
So, i dont know what im doing wrong. Im using NSObject like in tutorial.
SharedData.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface SharedData : NSObject {
NSString *MeuNome;
}
#property (nonatomic, retain) NSString *MeuNome;
#end
SharedData.m
#import "SharedData.h"
#implementation SharedData
#synthesize MeuNome;
- (void) dealloc {
self.MeuNome = nil;
[super dealloc];
}
#end
FirstStepViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "SharedData.h"
#interface FirstStepViewController : UIViewController {
IBOutlet SharedData *sharedData;
IBOutlet UITextField *campoNome;
}
#property (nonatomic, retain) UITextField * campoNome;
#property (nonatomic, retain) SharedData *sharedData;
- (IBAction) takeNextStep: (id) sender;
#end
FirstStepViewController.m
#import "FirstStepViewController.h"
#import "SecondStepViewController.h"
#import "LuconeAppDelegate.h"
#implementation FirstStepViewController
#synthesize campoNome, sharedData;
- (IBAction) takeNextStep : (id) sender{
// declaracao de shared data
[sender resignFirstResponder];
self.sharedData.MeuNome = self.campoNome.text;
// faz animacao para proximo slide
SecondStepViewController *varSecondViewController = [[SecondStepViewController
alloc] initWithNibName:#"SecondStepViewController" bundle:nil ];
[self.navigationController pushViewController:varSecondViewController
animated: YES];
[self navigationController].navigationBarHidden = NO;
}
- (void)viewDidLoad {
[self navigationController].navigationBarHidden = YES;
[super viewDidLoad];
}
- (void)dealloc {
self.sharedData = nil;
//self.campoNome = nil;
[super dealloc];
}
#end
SecondStepViewController.h
#import <UIKit/UIKit.h>
#import "SharedData.h"
#interface SecondStepViewController : UIViewController {
IBOutlet SharedData *sharedData;
IBOutlet UILabel *nome;
}
#property (nonatomic, retain) SharedData *sharedData;
#property (nonatomic, retain) UILabel *nome;
#end
SecondStepViewController.m
#import "SecondStepViewController.h"
#import "SharedData.h"
#implementation SecondStepViewController
#synthesize nome, sharedData;
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = #"step two";
self.nome.text = self.sharedData.MeuNome;
}
- (void)dealloc {
self.sharedData = nil;
[super dealloc];
}
#end
What's wrong?
Thanks!
There are three small problems with your code.
IBOutlet is only for controls that you put on your view using interface builder e.g. UIButtons, UILabels. So it is unnecessary for instances of SharedData to be IBOutlets. Furthermore if you create your interface programmatically then using IBOutlet is again unnecessary.
You Declare that sharedData is an instance of SharedData class but you do not instantiate it. in your FirstStepViewController.m before you set any of sharedData's properties you should add the following code:
sharedData = [[sharedData alloc] init];
after that you can do:
self.sharedData.MeuNome = self.campoNome.text;
if you omit the "self." the code should work just as fine.
Finally before pushing the second view controller to the navigation stack you have to assign the sharedData object in your first view controller to sharedData in your second view controller.
in your FirstStepViewController.m add:
[varSecondViewController sharedData] = [self sharedData];
before:
[self.navigationController pushViewController:varSecondViewController
animated: YES];
Finally make sure you have connected all your outlets correctly in interface builder and everything should run perfectly then :)

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;