如何从子类更改父类的属性?

时间:2013-12-03 12:54:59

标签: ios properties

我正在使用Xcode中的iPhone应用程序。 我有2个类视图控制器。一个父母和一个儿童班。父类称为“RaknaLista”,子类称为“P_Format”。

在P_Format中,您可以更改2个标签中显示的字符串(valdBreddLabel& valdHojdLabel)。当您按下保存并返回到RaknaLista时,我希望值显示在名为“minTrycksaktext”的TextView中,但它不起作用,它只在值的位置显示(null)。 有人可以帮助我,说出我做错了吗?

RaknaLista.h:

#import <UIKit/UIKit.h>

@interface RaknaLista : UIViewController

@property (nonatomic, retain)  IBOutlet UITextView *minTrycksaktext;

@property (nonatomic, assign) NSString *format_Bredd;
@property (nonatomic, assign) NSString *format_Hojd;

@end

RaknaLista.m:

#import "RaknaLista.h"


@interface RaknaLista ()

@end

@implementation RaknaLista

@synthesize format_Bredd,format_Hojd;
@synthesize minTrycksaktext;

- (void)viewDidLoad
{
    [super viewDidLoad];


    minTrycksaktext.text = [NSString stringWithFormat:@"Format: \n\nBredd: %@ \nHöjd: %@ \n", format_Bredd, format_Hojd];

}

P_Format.h:

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

@interface P_Format : RaknaLista <UITextFieldDelegate>

@property (nonatomic, retain) IBOutlet UILabel *valdBreddLabel;
@property (nonatomic, retain) IBOutlet UILabel *valdHojdLabel;

-(IBAction)sparaPressed:(id)sender;

@end

P_Format.m

#import "P_Format.h"

@interface P_Format ()

@end

@implementation P_Format

@synthesize valdBreddLabel;
@synthesize valdHojdLabel;


-(IBAction)sparaPressed:(id)sender{

RaknaLista *raknalista = [[RaknaLista alloc]init];

raknalista.format_Bredd = valdBreddLabel.text;
raknalista.format_Hojd = valdHojdLabel.text;

}


@end

4 个答案:

答案 0 :(得分:1)

有几点想法:

  1. 很难理解你在这里要做什么。例如,您有一个方法

    -(IBAction)sparaPressed:(id)sender{
    
        RaknaLista *raknalista = [[RaknaLista alloc]init];
    
        raknalista.format_Bredd = valdBreddLabel.text;
        raknalista.format_Hojd = valdHojdLabel.text;
    }
    

    这没有多大意义。您正在创建RaknaLista的新实例,设置format_Breddformat_Hojd,但随后让raknalista超出范围,从而丢弃您刚刚保存的值。

  2. P_Format作为RaknaLista的子类并不合理。如果它们是两个不同的视图控制器,它们每个都应该是UIViewController的子类,而不是一个是另一个的子类。不要将视图控制器所呈现的序列与类层次结构混淆。

  3. 如果您希望P_Format更新RaknaLista,则应使用委托协议模式。

    首先,在P_Format.h,你

    • 使其成为UIViewController子类;

    • 定义协议(即P_Format在要更新RaknaLista时将调用的方法名称是什么);以及

    • 定义delegate(这将是指向RaknaLista对象的指针)。

    因此,P_Format.h看起来像:

    #import <UIKit/UIKit.h>
    
    @protocol P_FormatDelegate <NSObject>
    
    - (void)updateBredd:(NSString *)bredd hojd:(NSString *)hojd;
    
    @end
    
    @interface P_Format : UIViewController
    
    @property (nonatomic, retain) IBOutlet UILabel *valdBreddLabel;
    @property (nonatomic, retain) IBOutlet UILabel *valdHojdLabel;
    
    @property (nonatomic, assign) id<P_FormatDelegate> delegate;
    
    -(IBAction)sparaPressed:(id)sender;
    
    @end
    

    因此,应将RaknaLista.h定义为符合P_FormatDelegate

    #import <UIKit/UIKit.h>
    #import "P_Format.h"
    
    @interface RaknaLista : UIViewController <P_FormatDelegate>
    
    @property (nonatomic, retain) IBOutlet UITextView *minTrycksaktext;
    
    @property (nonatomic, assign) NSString *format_Bredd;
    @property (nonatomic, assign) NSString *format_Hojd;
    
    @end
    

    现在,当RaknaLista想要展示P_Format时,您就像现在一样,但也要确保将delegate的{​​{1}}属性设置为引用P_Format实例。例如,当RaknaLista想要转换为RaknaLista.m时,假设您使用的是NIB并以模态方式呈现P_Format,那么您可以执行以下操作:

    P_Format

    此外,- (void)presentPFormat { P_Format *controller = [[P_Format alloc] initWithNibName:nil bundle:nil]; controller.delegate = self; [self presentViewController:controller animated:YES completion:nil]; [controller release]; // this is not needed in ARC } 必须实施RaknaLista.m协议定义的方法,以便P_FormatDelegate更新P_Formatformat_Bredd

    format_Hojd

    最后,当- (void)updateBredd:(NSString *)bredd hojd:(NSString *)hojd { self.format_Bredd = bredd; self.format_Hojd = hojd; } 要更新P_Format中的高度(hojd)和宽度(bredd)属性时,它将调用定义的RaknaLista方法通过updateBredd:hojd:协议。它会在呈现P_FormatDelegate视图控制器之前使用delegate设置的RaknaLista属性调用该方法:

    P_Format
  4. 我知道这看起来很多,但这是一个你应该熟悉的模式,因为它在Cocoa Touch开发中很常见。协议是“子”更新“父”的接口。 “child”将具有- (IBAction)sparaPressed:(id)sender{ [self.delegate updateBredd:self.valdBreddLabel.text hojd:self.valdHojdLabel.text]; } 属性(因此它知道调用协议中定义的方法的对象)。

    顺便说一句,我正在使用你的“父母”和“孩子”术语,但我建议你在谈论视图控制器时不要使用这些术语,因为这些术语在Cocoa Touch中实际上意味着一个非常特殊的含义,特别是自定义容器视图控制器的高级主题(也就是视图控制器包含)。我假设你在这里没有这样做,我使用这些术语只是为了与你的问题保持一致,但是你应该避免使用“父”和“孩子“控制器术语,除非进行遏制。

    最后,我同意其他人的观点,认为这些课程的名称并不理想(但我不会因为害怕已经对你太过分而改变它们)。但一般情况下,我建议将delegate替换为RaknaListaRaknaViewControllerP_Format或类似内容。同样,DetailsViewController应该只是format_Breddbredd只是format_Hojd。有关命名约定的更多信息,请参阅Coding Guidelines for Cocoa

    请参阅ProtocolsDelegation上的Apple文档,其中提供了许多其他精彩文档的链接。

答案 1 :(得分:0)

如果让我们说这是你的父类

@interface ParentViewController : UIViewController

@property (nonatomic) NSArray *items;

@end

你需要的是从儿童班设置项目,让我们说

#import "ParentViewController.h"

@interface ChildViewController : ParentViewController

@end

然后你应该把它放在父类

#import "ParentViewController.h"

@interface ParentViewController ()

@end

@implementation ParentViewController

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

    _items = [[NSArray alloc] init];
}

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

- (void)setItems:(NSArray *)items {
    _items = items;
}

并在子类中实现以下方法

#import "ChildViewController.h"

@implementation ChildViewController

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

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

- (void)setItems:(NSArray *)items {

    [super setItems:items];
    // Write any custom code

}

答案 2 :(得分:-1)

查看创建协议Working with protocols

或类似此事Passing data between controllers

答案 3 :(得分:-1)

这是我发现在视图控制器之间传递数据的最佳和最简单的方法:

http://www.leesilver.net/1/post/2011/08/passing-data-between-view-controllers-in-objective-c.html