2013-12-03 4 views
-1

Я работаю с iPhone приложение в Xcode. У меня есть 2 класса, которые являются контроллерами представлений. Один родительский и один дочерний класс. Родительский класс называется «RaknaLista», а дочерний класс называется «P_Format».Как изменить свойство родительского класса из дочернего класса?

В P_Format вы можете изменить 2 строки, которые отображаются в 2 ярлыках (valdBreddLabel & valdHojdLabel). Когда вы нажмете «Сохранить» и вернитесь в RaknaLista, я хочу, чтобы значения отображались в TextView под названием «minTrycksaktext», но он не работает, он показывает только (нуль) в месте для значений. Может кто-нибудь помочь мне, пожалуйста, и сказать, что я делаю неправильно?

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 
+1

Вы действительно должны смотреть на именование конвеции для ios. Использование того, что нравится шведскому в вашем коде, не является хорошей практикой для любого кода. это просто подсказка. – Vaionixx

+0

Вы используете ARC? Вы используете 'assign' и' keep', которые являются квалификаторами предварительной ARC-памяти, поэтому я считаю, что вы не используете ARC. Но у вас нет операторов 'release', поэтому, если вы используете ARC, вы будете утечки. Я хочу ответить на вопрос, но хотел бы знать, используете ли вы ARC или нет. – Rob

+0

Вы используете ARC? Вы используете 'assign' и' keep', которые являются квалификаторами предварительной ARC-памяти, поэтому я считаю, что вы не используете ARC. Но у вас нет операторов 'release', поэтому, если вы используете ARC, вы будете утечки. Кроме того, вы используете раскадровки или NIB? Без ответов на эти вопросы людям сложно рекомендовать необходимые исправления для вашего кода. – Rob

ответ

1

Пара мысли:

  1. Трудно понять, что вы пытаетесь чтобы сделать здесь. Например, у вас есть метод

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

    Это не имеет смысла. Вы создаете новый экземпляр RaknaLista, устанавливая format_Bredd и format_Hojd, но затем позволяя raknalista выпадать из области видимости, тем самым отбрасывая только что сохраненные значения.

  2. Это не имеет смысла делать P_Format подклассом RaknaLista. Если это два разных контроллера представлений, каждый из них должен быть подклассами UIViewController, а не одним из подклассов другого. Не путайте последовательность, в которой контроллеры представлений представлены иерархией классов.

  3. Если вы хотите, чтобы P_Format для обновления RaknaLista, вы должны использовать шаблон протокола делегата.

    Во-первых, в P_Format.h, вы

    • сделать его UIViewController подкласс;

    • определяют протокол (т.что такое имя метода, которое P_Format выдает, когда оно хочет обновить RaknaLista); и

    • определить a 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 свойство P_Format для реферирования ce RaknaLista экземпляр. Например, когда RaknaLista.m хочет перейти в P_Format, если вы использовали NIBS и представляли 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_Format обновить format_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 вида:

    - (IBAction)sparaPressed:(id)sender{ 
    
        [self.delegate updateBredd:self.valdBreddLabel.text hojd:self.valdHojdLabel.text]; 
    } 
    

Я знаю, что выглядит как много, но это шаблон, с которым вы действительно должны быть знакомы, потому что это очень распространено в разработке Cocoa Touch. Протокол - это интерфейс, посредством которого «ребенок» обновляет «родительский». «Ребенок» будет иметь свойство delegate (поэтому он знает, на каком объекте вызывается тот метод, определенный в протоколе).

Кстати, я использую терминологию «родительский» и «ребенок», но я бы посоветовал вам воздерживаться от этих терминов, когда речь идет о контроллерах представлений, потому что эти термины фактически подразумевают особое значение в Cocoa Touch, в частности, расширенную тему пользовательских диспетчеров контейнеров (например, сдерживание контроллера). Я предполагаю, что вы не делаете этого здесь, и я использовал термины, чтобы соответствовать вашему вопросу, но вы должны воздерживаться от «родительских» и «детская» контрольная терминология, если не делается сдерживания.

Наконец-то я согласен с другими в том, что имена этих классов не идеальны (но я воздержался от их изменения, опасаясь, что вы слишком сильно набросились на вас). , Я бы предложил заменить RaknaLista с чем-то вроде RaknaViewController и P_Format с DetailsViewController или что-то в этом роде. Аналогично, format_Bredd должен, вероятно, быть только bredd, а format_Hojd будет всего лишь hojd. Дополнительную информацию о соглашениях об именах см. В разделе Coding Guidelines for Cocoa.

См. Документацию Apple по телефонам Protocols и Delegation, которые содержат ссылки на многие другие замечательные документы.

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 

} 
Смежные вопросы