简体   繁体   English

在iPhone中的两个ViewController之间使用委托

[英]Using delegate between two viewcontrollers in iphone

I have two view controllers: view controller and viewcontroller2nd. 我有两个视图控制器:视图控制器和viewcontroller2nd。 I have UILabel in one of them and would like to change it when the button( named Go) in the viewcontroller2nd is clicked. 我在其中之一中拥有UILabel,并且当单击viewcontroller2nd中的按钮(名为Go)时想更改它。 I am using delegates and protocols to do it. 我正在使用委托和协议来做到这一点。

The code looks like this: 代码如下:

ViewController.h ViewController.h

#import <UIKit/UIKit.h>
#import "ViewController2nd.h"

@interface ViewController : UIViewController <SecondViewControllerDelegate>
{
    IBOutlet UILabel *lbl;
    ViewController2nd *secondview;

}
-(IBAction)passdata:(id)sender;

@end

ViewController.m ViewController.m

#import "ViewController.h"
#import "ViewController2nd.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void) changeLabel:(NSString*)str{
    lbl.text = str;
}

-(IBAction)passdata:(id)sender{
    ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil];
    [self presentViewController:second animated:YES completion:NULL];
}

@end

Viewcontroller2nd.h Viewcontroller2nd.h

#import <UIKit/UIKit.h>


@protocol SecondViewControllerDelegate <NSObject>
@optional
-(void) changeLabel:(NSString*)str;
@end

@interface ViewController2nd : UIViewController{

    IBOutlet UIButton *bttn;
    id <SecondViewControllerDelegate> delegate;

}

@property (retain) id delegate;

-(IBAction)bttnclicked;
-(IBAction)back:(id)sender;
@end

ViewController2nd.m ViewController2nd.m

#import "ViewController2nd.h"
#import "ViewController.h"

@interface ViewController2nd ()

@end

@implementation ViewController2nd

@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(IBAction)bttnclicked{
   [[self delegate] changeLabel:@"Hello"];
}

-(IBAction)back:(id)sender{
    [self dismissViewControllerAnimated:YES completion:NULL];
}

@end

The passing of the control between the two views is working correctly. 在两个视图之间传递控件正常工作。 However, when i click the go button in the viewcontroller2nd, it doesn't change the value of the label to Hello. 但是,当我单击viewcontroller2nd中的go按钮时,它不会将标签的值更改为Hello。 What is wrong with the code? 代码有什么问题? Need some guidance. 需要一些指导。

It seems you never set the delegate. 似乎您从未设置过代理。 You can do it in your passData method : 您可以在passData方法中执行此操作:

-(IBAction)passdata:(id)sender{
    ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil];
    second.delegate = self;
    [self presentViewController:second animated:YES completion:NULL];
}

Hm, try the following in your changeLabel delegate method: 嗯,请在您的changeLabel委托方法中尝试以下操作:

-(void) changeLabel:(NSString*)str{
    lbl.text = str;
    [lbl setNeedsDisplay];
}

EDIT: 编辑:

Other than that: Your label is a IBOutlet, right? 除此之外:您的标签是IBOutlet,对吗? Did you connect the label in your xib with the IBOutlet property (ie lbl) correctly in interface builder with the files owner 您是否在接口构建器中使用文件所有者正确地将xib中的标签与IBOutlet属性(即lbl)连接在一起

If you want to do this by using delegates then change passdata like: 如果要通过使用委托来执行此操作,请更改passdata例如:

 -(IBAction)passdata:(id)sender
  {
        ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil];
        [second setDelegate:self];
        [self presentViewController:second animated:YES completion:NULL];
  }

You can do this without delegates. 您可以在没有委托的情况下执行此操作。 Just create a object of ViewController in secondView and synthesize it like: 只需在secondView中创建ViewController的对象并进行合成即可,如下所示:

#import "ViewController.h"
@interface ViewController2nd : UIViewController
{

    IBOutlet UIButton *bttn;
    ViewController  *parent;

}

@property (nonatomic, assign) ViewController  *parent;

-(IBAction)bttnclicked;
-(IBAction)back:(id)sender;
@end

and in the passdata change it like 并在passdata更改为

-(IBAction)passdata:(id)sender
{
    ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil];
    [second setParent:self];
    [self presentViewController:second animated:YES completion:NULL];
}

and change the bttnclicked like: 然后将bttnclicked更改为:

-(IBAction)bttnclicked
{
   [parent changeLabel:@"Hello"];
}

I wrote following for you! 我为您写了以下内容!

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (strong, nonatomic) IBOutlet UILabel *label;

@end

#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController () <ViewController2Delegate>

@end

@implementation ViewController

-(void)passdata:(NSString *)data
{
    self.label.text = data;
}

- (IBAction)buttonClicked:(id)sender {
    ViewController2 *v = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil];
    v.delegate = self;
    [self presentViewController:v animated:YES completion:nil];
}

@end

#import <UIKit/UIKit.h>

@protocol ViewController2Delegate <NSObject>

- (void)passdata:(NSString*)data;

@end

@interface ViewController2 : UIViewController

@property(assign, nonatomic) id<ViewController2Delegate> delegate;

@end

#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (IBAction)buttonClicked:(id)sender {
    [self.delegate passdata:@"hello"];
}

- (IBAction)backButtonClicked:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
  • You don't need to import the header "ViewController2nd.h" in the both ViewController.h and ViewController.m 您无需在ViewController.h和ViewController.m中都导入标头“ ViewController2nd.h”
  • You declare the UILabel without property like, @property (strong, nonatomic). 您声明UILabel没有@property之类的属性(强,非原子)。
  • May be, You didn't properly map the UILabel to your .storyboard or .xib file. 可能是,您没有正确地将UILabel映射到您的.storyboard或.xib文件。
  • You forget to assign the second view controller delegate while calling the controller 您在调用控制器时忘记分配第二个视图控制器委托

     ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil]; second.delegate = self; [self presentViewController:second animated:YES completion:NULL]; 

If anyone is using storyboard for viewcontrollers navigation. 如果有人将情节提要用于视图控制器导航。

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier hasPrefix:@"view_to_capture"]) {
            ViewController2nd *destination = segue.destinationViewController;
            destination.delegate = self;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM