Xcode:如何从子类访问方法?

时间:2013-01-07 23:04:04

标签: objective-c ios xcode oop

当我尝试从SubView访问主ViewController中的方法时,我的应用程序崩溃了。

请帮忙。

我的主ViewController中有一个UIButton,用于更改UILabel中的文本,UILabel也在我的主视图中。我在SubView中有一个UIButton,它应该通过从主ViewController访问相同的方法再次更改字符串。但应用程序崩溃了。

这是我的代码:

主ViewController

ViewController.h

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

@interface ViewController : UIViewController

@property (nonatomic, strong) UILabel *label;
@property (nonatomic, retain) UIButton *mainClassButton;

- (void) setLabelTo:(NSString *)copy;

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize label;
@synthesize mainClassButton;

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

    self.label = [[UILabel alloc] initWithFrame:CGRectMake(30.0, 30.0, 200.0, 30.0)];
    self.label.text = @"Let's Go Mets!";
    [self.view addSubview:label];

    mainClassButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    mainClassButton.frame = CGRectMake(30.0, 70.0, 200.0, 30.0);
    [mainClassButton setTitle:@"Main Class Button" forState:UIControlStateNormal];
    [mainClassButton addTarget:self action:@selector(touchAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:mainClassButton];

    SubViewController *subViewController = [[SubViewController alloc] init];
    subViewController.view.backgroundColor = [UIColor clearColor];
    [self.view addSubview:subViewController.view];

    [self.view bringSubviewToFront:self.mainClassButton];
}

- (IBAction)touchAction:(UIButton *) sender
{
    [self setLabelTo:@"Here we go Yankess!"];
}

- (void) setLabelTo:(NSString *)copy
{
    self.label.text = copy;
}

Sub ViewController

SubViewController.h

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

@interface SubViewController : UIViewController

@property (nonatomic, retain) UIButton *subClassButton;

@end

SubViewController.m

@implementation SubViewController

@synthesize subClassButton;

- (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.

    subClassButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    subClassButton.frame = CGRectMake(30.0, 115.0, 200.0, 30.0);
    [subClassButton setTitle:@"Sub Class Button" forState:UIControlStateNormal];
    [subClassButton addTarget:self action:@selector(touchAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:subClassButton];

}

- (IBAction)touchAction:(UIButton *) sender
{
    ViewController *vc = [[ViewController alloc] init];

    [vc setLabelTo:@"If you ask me, I prefer the White Sox."];
}

我仍然是Xcode和Objective-C的新手,我很感激您提供的任何帮助。

由于

3 个答案:

答案 0 :(得分:1)

您需要在-setLabelTo内的ViewController现有实例上致电-[SubViewController touchAction:] - 目前,您正在创建ViewController的新实例并致电-setLabelTo:关于那个新实例。

要在-setLabelTo上致电ViewController,我们需要对ViewController的引用。

UIViewController提供了一个属性parentViewController,在理想的情况下,该属性会为您的SubViewController提供ViewController个引用。但是,在这种情况下,它没有提供这样的参考。您将SubViewController的视图添加为ViewController的子视图,但是SubViewController添加为{{1}的子视图控制器}}。 (另请参阅this questionthe accepted answer。)要解决此问题,请在ViewController中添加一行

-[ViewController viewDidLoad]

[self addChildViewController:subViewController];

给你

SubViewController *subViewController = [[SubViewController alloc] init];

此时,您的SubViewController *subViewController = [[SubViewController alloc] init]; [self addChildViewController:subViewController]; subViewController.view.backgroundColor = [UIColor clearColor]; [self.view addSubview:subViewController.view]; SubViewController的子视图控制器,您的ViewController视图是SubViewController视图的子视图。

此时,您可以将ViewController的实施更改为

-[SubViewController touchAction:]

将在原始- (IBAction)touchAction:(UIButton *) sender { ViewController *vc = self.parentViewController; [vc setLabelTo:@"If you ask me, I prefer the White Sox."]; } 上调用-setLabelTo:,而不是创建新实例并导致崩溃。

答案 1 :(得分:0)

您必须获取子视图控制器的父视图控制器:self.parentViewController您在subViewController中的touchAction中所做的是创建一个新的视图控制器。

答案 2 :(得分:0)

看看以下几行:

ViewController *vc = [[ViewController alloc] init];
[vc setLabelTo:@"If you ask me, I prefer the White Sox."];

您正在实例化ViewController,但未调用viewDidLoad。在那里,您使用setLabelTo方法实例化要设置标题的UILabel。

viewDidXXXX和viewWillXXXX在Storyboard或某些UINavigationController中使用时会自动调用。