Jak przekazać parametr do widoku “rodzica” (parent view)
Posted: September 10th, 2010 | Author: plusz | Filed under: Xcode solutions | Comments Off on Jak przekazać parametr do widoku “rodzica” (parent view)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
IBOutlet UILabel *myLabel;
IBOutlet UITableView *wynagrodzeniaTable;
}
@property (nonatomic, assign) id
@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
