【问题标题】:Using delegate between two viewcontrollers in iphone在 iphone 的两个视图控制器之间使用委托
【发布时间】:2012-10-23 09:21:13
【问题描述】:

我有两个视图控制器:视图控制器和 viewcontroller2nd。我在其中一个中有 UILabel,并且希望在单击 viewcontroller2nd 中的按钮(名为 Go)时更改它。我正在使用委托和协议来做到这一点。

代码如下所示:

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

#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

#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

#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

两个视图之间的控件传递工作正常。但是,当我单击 viewcontroller2nd 中的 go 按钮时,它不会将标签的值更改为 Hello。代码有什么问题?需要一些指导。

【问题讨论】:

  • 你检查过第一个视图控制器的 changeLabel 被调用了吗?尝试放置 NSLog 并确认它正在被调用。
  • 嗯,这是因为您没有将委托传递给第二个控制器。此外,代表永远不会被保留,否则您会有保留周期 - 内存问题。您应该在第二个控制器中将其声明为分配。

标签: iphone ios delegates protocols


【解决方案1】:

您似乎从未设置过委托。 您可以在您的 passData 方法中执行此操作:

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

【讨论】:

  • self,对不起,我同时在做 csharp,所以我有点困惑 ^^
  • 您确定调用了 bttnclicked 方法并且委托不是 nil 吗? (你能验证一下吗:))
  • 在您的 pasData 方法中添加以下行: NSLog(@"Function Called");并在您的 bttnclicked 方法中执行类似的操作: if(delegate == nil) NSLog(@"Delegate is nil");
【解决方案2】:

嗯,在您的 changeLabel 委托方法中尝试以下操作:

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

编辑:

除此之外: 你的标签是 IBOutlet,对吧?您是否在文件所有者的界面构建器中正确地将 xib 中的标签与 IBOutlet 属性(即 lbl)连接起来

【讨论】:

  • 您的标签是 IBOutlet,对吗?您是否在文件所有者的界面构建器中正确地将 xib 中的标签与 IBOutlet 属性(即 lbl)连接起来?
  • 是的..我确实在界面生成器中正确连接了属性...仍然无法更改它...
【解决方案3】:

如果您想通过使用委托来执行此操作,请更改 passdata 之类的:

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

您可以在没有委托的情况下执行此操作。 只需在 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

并在passdata 中进行更改

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

并将bttnclicked 更改为:

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

【讨论】:

  • 我已经编辑了我的答案,请在单击的按钮上添加一个 nslog 并更改标签方法。
【解决方案4】:

我为你写了以下内容!

#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

【讨论】:

    【解决方案5】:
    • 您不需要在 ViewController.h 和 ViewController.m 中都导入头文件“ViewController2nd.h”
    • 您声明的 UILabel 没有属性,例如 @property(强,非原子)。
    • 可能是,您没有正确地将 UILabel 映射到您的 .storyboard 或 .xib 文件。
    • 您在调用控制器时忘记分配第二个视图控制器委托

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

    如果有人使用故事板进行视图控制器导航。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多