Home > Xcode solutions > Jak przekazać parametr do widoku “rodzica” (parent view)

Jak przekazać parametr do widoku “rodzica” (parent view)

September 10th, 2010 Leave a comment Go to comments

Passing parameters to parent object in Objective-C Często w aplikacji posiadającej wiele widoków potrzebujemy wyświetlić dodatkowy widok, na którym użytkownik wprowadzi parametry (lub wybierze z tabeli). Chcemy tą informację wykorzystać w naszym nadrzędnym obiekcie.

Przykład:
Wyświetlany ekran kalkulatora (zobacz aplikację Savings Calculator with Tax w App Store).
Po zmianie kapitalizacji lub okresu (czyli wybraniu wartości z tabelki na innym widoku), chcemy wykonać ponownie obliczenia z uwzględnieniem zmienionych wartości.

Możemy zastosować następujące metody:
1. wykorzystujemy subview zamiast widoków i nie tworzymy dodatkowych klas.
2. wykorzystujemy Notification Center
3. Wykorzystujemy delegowanie obiektów i protokół

Omówmy poszczególne metody:

1. tworzymy subView i ładujemy je jako frame.
Ta metoda jest doskonale opisana w aplikacji Formulaic w dokumentacji Apple.
subview nie jest nowym obiektem więc ma dostęp do wszystkich atrybutów i metod obiektu z którego jest wywoływany.
W przypadku małych aplikacji może to być najszybsza metoda, ale cała logika aplikacji jest w jednym, nadrzędnym obiekcie.
Zauważyłem ponadto, że w przypadku gry pojawia się “In-Call” bar, aplikacja wyświetla wszystkie dotychczas zainicjowane subviews, mimo, że ich położenie zostało ustalone poza widocznym ekranem. Badam problem.

Jak zainicjować subview?

CGRect frame = okresView.frame;
frame.origin.x = frame.size.width;
if ( [okresView superview] == nil )
{
[self.view addSubview:okresView];
}

okresView.frame = frame;
[okresDataTableView reloadData]; // przeładowanie tabeli na subwidoku

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.5];
frame.origin.x = 0;
okresView.frame = frame;
[UIView commitAnimations];

oczywiście w pliku nagłówkowym deklarujemy:

IBOutlet UIView *okresView;

2. Notification Center – przesyłanie notyfikacji pomiędzy obiektami

Metoda ta jest opisane w dokumencie “Notification Programming Topics” w pomocy Xcode

W obiekcie który ma “nasłuchiwać” odpowiedzi innych obiektów, najlepiej w metodzie viewDidLoad definiujemy obserwer

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(zmienLabelSekcjiMethod:) name:@"zmienLabelSekcji" object:nil];

definiujemy również metodę obsługującą zdarzenie

-(void)zmienLabelSekcjiMethod:(id)sender {
labelsekcji.text = (NSString *)[sender object];
}

Obiekt będzie teraz “nasłuchiwał” komunikatu o nazwie “zmienLabelSekcji”

W obiekcie, który ma wysłać komunikat, wpisujemy kod:

[[NSNotificationCenter defaultCenter] postNotificationName:@"zmienLabelSekcji" object:[NSString stringWithFormat:@"%d",wybranaSekcja]];

przesyłany obiekt to w naszym przypadku string: [NSString stringWithFormat:@"%d",wybranaSekcja]]

3. kolejna metoda to zdefiniowanie protokołu oraz delegate dzięki którym obiekt dziecko będzie mógł komunikować się z rodzicem

Zaczniemy od zdefiniowania protokołu w pliku nagłówkowym klasy dziecka:

@protocol FlipsideViewControllerDelegate;

@interface FlipsideViewController : UIViewController {
id delegate;
IBOutlet UILabel *myLabel;
IBOutlet UITableView *wynagrodzeniaTable;
}

@property (nonatomic, assign) id delegate;
@property (nonatomic) NSInteger testNumber;
- (IBAction)done:(id)sender;
@end

@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller selectedItem:(NSInteger)selectedItem;
@end

w pliku rodzica definiujemy obsługę protokołu przez naszą klasę

@interface MainViewController : UIViewController {
...

Po tej definicji nasza klasa MUSI implementować obsługę metod protokołu, więc dodajemy kod:

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller selectedItem:(NSInteger)selectedItem{
mySelectedRow.text=[NSString stringWithFormat:@"%d" ,selectedItem];
[self dismissModalViewControllerAnimated:YES];
}

Pozostaje do zaimplementowania kod informujący o delegacji oraz wywołanie metody klasy delegującej.
W obiekcie “rodzica” tworząc obiekt ustawiamy atrybut delegate wskazując na “siebie”

FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
controller.delegate = self;

W obiekcie dziecka wywołujemy metodę obiektu rodzica:

[self.delegate flipsideViewControllerDidFinish:self selectedItem:testNumber];

Kod aplikacji realizującej przekazywanie parametrów metodą 2 i 3 znajduje się w przykładowej aplikacji załączonej poniżej.

Passing parameters to parent object in Objective-C

Tags:
  1. No comments yet.
  1. No trackbacks yet.