iOS programming in 2010

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

Posted: September 10th, 2010 | Author: | 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 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


Comments are closed.