After asking some questions, I learned how to send orders from one view controller to another and managed to write the code its working but nothing happens...
In my
Rereading your question, you ask how your first view controller can open the second view controller and set a text box. If that is, indeed, what you are trying to do, it's a far simpler question, no delegate protocol or delegates required at all.
The two previous answers were informed by the discussion of delegates, but that's designed to solve a different problem. Delegates are only required if you need your second controller to pass something back to the first controller. But if you just want your second controller to receive something from the first controller, it's as simple as:
// FirstViewController.h
#import <UIKit/UIKit.h>
@interface FirstViewController : UIViewController
@end
with an implementation like:
// FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
@implementation FirstViewController
- (NSString *)generateRandomText
{
NSString *result;
int random_num;
random_num = (arc4random() % 5 - 1) + 1;
if (random_num == 1)
result = @"hello1";
else if (random_num == 2)
result = @"hello2";
else if (random_num == 3)
result = @"hello3";
else if (random_num == 4)
result = @"hello4";
return result;
}
// if you're using NIBs, it might be something like...
// you only need this method if you're using NIBs and you've manually hooked a button up to this
// if you're using segues, get rid of `goToNextViewController` and just use the following `prepareForSegue
- (IBAction)goToNextViewController:(id)sender
{
SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
secondController.textFromParent = [self generateRandomText];
[self.navigationController pushViewController:secondController animated:YES];
}
// if you're using segues, give your segue an identifier, e.g. toSecondViewSegue, in Interface Builder and reference the exact same identifier here
// if you're not using segues, you don't need this prepareForSegue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"toSecondViewSegue"])
{
SecondViewController *destinationController = segue.destinationViewController;
destinationController.textFromParent = [self generateRandomText];
}
}
@end
And your second controller might look like:
// SecondViewController.h
#import <UIKit/UIKit.h>
@interface SecondViewController : UIViewController
@property (strong, nonatomic) NSString *textFromParent;
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
With an implementation like:
// SecondViewController.m
#import "SecondViewController.h"
@implementation SecondViewController
@synthesize textFromParent = _textFromParent;
@synthesize label = _label;
- (void)viewDidLoad
{
[super viewDidLoad];
self.label.text = self.textFromParent;
}
@end
Your first controller should, when it instantiates the second controller, set the second's delegate to point back to the first view controller. Thus your first view controller might look like:
// FirstViewController.h
#import <UIKit/UIKit.h>
@protocol FirstViewControllerDelegate <NSObject>
- (void)dealWithButton;
@end
@interface FirstViewController : UIViewController <FirstViewControllerDelegate>
@end
with an implementation like:
// FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
@implementation FirstViewController
- (IBAction)goToNextViewController:(id)sender
{
SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
secondController.delegate = self;
[self.navigationController pushViewController:secondController animated:YES];
}
- (void)dealWithButton
{
NSLog(@"Dealt with button from second controller");
}
@end
And your second controller might look like:
// SecondViewController.h
#import <UIKit/UIKit.h>
#import "FirstViewController.h"
@class FirstViewController;
@interface SecondViewController : UIViewController
@property (weak, nonatomic) id<FirstViewControllerDelegate> delegate;
@property (weak, nonatomic) IBOutlet UILabel *label;
- (IBAction)buttonPressed:(id)sender;
@end
With an implementation like:
// SecondViewController.m
#import "SecondViewController.h"
@implementation SecondViewController
@synthesize delegate = _delegate;
@synthesize label = _label;
- (IBAction)buttonPressed:(id)sender
{
int random_num;
random_num = (arc4random() % 5 - 1) + 1;
if (random_num == 1)
self.label.text = @"hello1";
else if (random_num == 2)
self.label.text = @"hello2";
else if (random_num == 3)
self.label.text = @"hello3";
else if (random_num == 4)
self.label.text = @"hello4";
[self.delegate dealWithButton];
}
@end
Update:
Your original question did not make it clear as to whether you wanted the label to be on the first controller or the second. My answer above assumed you wanted it on the second controller, but in retrospect, you may have wanted it on the first controller (the delegate). If so, the following code does that. Note carefully that I don't just update the first view controller's label in dealWithButton
, because that's dangerous, because you don't know if the view is visible (could have been unloaded if you received a didReceiveMemoryWarning
). So I wait for viewWillAppear
. So again, the first view controller:
// FirstViewController.h
#import <UIKit/UIKit.h>
@protocol FirstViewControllerDelegate <NSObject>
- (void)dealWithButton;
@end
@interface FirstViewController : UIViewController <FirstViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
And its implementation:
// FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
{
NSString *_labelText;
}
@end
@implementation FirstViewController
@synthesize label = _label;
// if you're using storyboards, it would be like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"delegateSegue"])
{
SecondViewController *destinationController = segue.destinationViewController;
FirstViewController *sourceController = segue.sourceViewController;
destinationController.delegate = sourceController;
}
}
// if not using storyboards, you probably have a button like:
- (IBAction)goToNextViewController:(id)sender
{
SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
secondController.delegate = self;
[self.navigationController pushViewController:secondController animated:YES];
}
- (void)dealWithButton
{
// note, because this is being called by the second view controller, you should *not* update the UI
// directly, because you can't be assured this view controller's view is still in memory (if you got
// a didReceiveMemoryWarning while on the second view controller, this first view controller will
// stay in memory, but its view could have been released). So save what you want the label to be,
// and update it on viewWillAppear (and if the view was released, it will be reloaded by the time
// you hit viewWillAppear.
//
// clearly, if you were doing view controller containment and this was the parent view, you wouldn't
// want to do this. But I assume you're dealing with a simple push/present view controller situation.
int random_num;
random_num = (arc4random() % 5 - 1) + 1;
if (random_num == 1)
_labelText = @"hello1";
else if (random_num == 2)
_labelText = @"hello2";
else if (random_num == 3)
_labelText = @"hello3";
else if (random_num == 4)
_labelText = @"hello4";
NSLog(@"Dealt with button from second controller");
}
- (void)viewWillAppear:(BOOL)animated
{
self.label.text = _labelText;
}
@end
And the second view controller:
// SecondViewController.h
#import <UIKit/UIKit.h>
#import "FirstViewController.h"
@class FirstViewController;
@interface SecondViewController : UIViewController
@property (weak, nonatomic) id<FirstViewControllerDelegate> delegate;
- (IBAction)buttonPressed:(id)sender;
@end
And its implementation:
// SecondViewController.m
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
@synthesize delegate = _delegate;
- (IBAction)buttonPressed:(id)sender
{
[self.delegate dealWithButton];
}
@end
Try to add the following method to your sayfa23's implementation:
- (void)viewDidLoad
{
vc1 = [[sayfa1 alloc] init];
vc1.delegate = self;
}
and remove vc1.delegate = self; from your dealWithButton1 method.
Edit: You have to understand that the method dealWithButton1 is never getting called because you are never sending the message to the object. Therefore, you are never setting the delegate of vc1. It is a good point to do some setup using the viewDidLoad method, which is called when the view is loaded. There you can alloc init (create an instance of) the sayfa1 class, and assign it to your property vc1. After you have allocated the object you can send messages to it. You can set the delegate then.
sayfa23.h
#import <UIKit/UIKit.h>
#import "sayfa1.h"
@interface sayfa23 : UIViewController <sayfa1Delegate>
{
IBOutlet UILabel *label;
}
@property (nonatomic, strong) sayfa1 *vc1 ;
@end
sayfa23.m
#import "sayfa23.h"
#import "sayfa1.h"
@interface sayfa23 ()
@end
@implementation sayfa23
@synthesize vc1;
- (void)viewDidLoad
{
vc1 = [[sayfa1 alloc] init];
vc1.delegate = self;
}
- (void)dealWithButton1
{
int random_num;
random_num = (arc4random() % 5 - 1) + 1;
if (random_num == 1)
{
label.text = @"hello1";
}
else if (random_num == 2)
label.text = @"hello2";
else if (random_num == 3)
label.text = @"hello3";
else if (random_num == 4)
label.text = @"hello4";
}
@end