Ablauf bei einem Aufruf mit Segue

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Ablauf bei einem Aufruf mit Segue

    Hallo zusammen,

    ich habe zwei View Controller die ich über ein Segue verbunden habe in einem Navigation Controller. Im ersten View Controller registriere ich im ViewDidLoad mit den folgenden Zeilen zwei Notifications :

    Quellcode

    1. [[NSNotificationCenter defaultCenter] addObserver:self
    2. selector:@selector(keyboardWasShown:)
    3. name:UIKeyboardDidShowNotification object:nil];
    4. [[NSNotificationCenter defaultCenter] addObserver:self
    5. selector:@selector(keyboardWillBeHidden:)
    6. name:UIKeyboardWillHideNotification object:nil];


    Wenn ich jetzt das gleiche im zweiten View Controller mache und dann über den Back-Button wieder zum ersten View Controller zurückgehe, bricht die App ohne Fehlermeldung ab. Jetzt ist meine Frage, wenn ich die folgenden zwei Zeilen im viewDidUnLoad einfüge :

    Quellcode

    1. // unregister for keyboard notifications while not visible.
    2. [[NSNotificationCenter defaultCenter] removeObserver:self
    3. name:UIKeyboardWillShowNotification
    4. object:nil];
    5. // unregister for keyboard notifications while not visible.
    6. [[NSNotificationCenter defaultCenter] removeObserver:self
    7. name:UIKeyboardWillHideNotification
    8. object:nil];

    Wird dann die Deregistrierung bei jedem Zurück-Button ausgeführt oder muss ich die Zeilen woanders einfügen ? Wie ist hier der Ablauf der viewXXX Proceduren beim Wechsel von ViewControllern über Segue ?
  • RWarnecke schrieb:

    Jetzt ist meine Frage, wenn ich die folgenden zwei Zeilen im viewDidUnLoad einfüge

    ..., dann werden die Zeilen ab iOS 6 nie aufgerufen, denn viewDidUnload ist seit iOS 6 deprecated.
    Deprecation Statement
    Views are no longer purged under low-memory conditions and so this method is never called.

    Ich würde die Methoden viewWillAppear: und viewWillDisappear: dafür verwenden.
  • Guten Morgen Michael,

    danke für Deine Antwort. Ich habe den Quelltext in die beiden Methoden viewWillAppear und viewWillDisappear eingesetzt. Leider habe ich immer noch das Problem, sobald die Notifications im zweiten View Controller aktiv sind und auch genutzt werden, das beim Zurückgehen die Anwendung einfach abbricht und im XCode in der main.m landet. Wenn ich die zwei Zeilen aus viewWillAppear aus kommentiere, habe ich das Problem nicht.
  • macmoonshine schrieb:

    Setz' mal einen Exception-Breakpoint.

    Wo soll ich den setzen ? Der Abbruch geht sofort in die main.m mit dem Fehler "".

    macmoonshine schrieb:

    Wie sehen die Observer-Methoden aus?

    Quellcode

    1. - (void)keyboardWasShown:(NSNotification *)notification
    2. {
    3. // Wird gebraucht, wenn der UIScrollView über das ganze Display ist.
    4. float viewWidth = self.view.frame.size.width;
    5. float viewHeight;
    6. switch((int)self.view.frame.size.height) {
    7. case 480:
    8. viewHeight = 340; // 3.5 inch Display
    9. break;
    10. case 568:
    11. viewHeight = 250; // 4 inch Display
    12. break;
    13. default:
    14. viewHeight = 340; // 3.5 inch Display
    15. break;
    16. }
    17. // Get the size of the keyboard from the userInfo dictionary.
    18. NSDictionary *keyboardInfo = [notification userInfo];
    19. CGSize keyboardSize = [[keyboardInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    20. float keyboardHeight = keyboardSize.height;
    21. if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])) {
    22. keyboardHeight = keyboardSize.width;
    23. // Also swap the view width and height.
    24. float temp = viewWidth;
    25. viewWidth = viewHeight;
    26. viewHeight = temp;
    27. }
    28. // Next, let's calculate the frame of the remaining viewable area.
    29. CGRect viewableAreaFrame = CGRectMake(0.0, 0.0, viewWidth, viewHeight - keyboardHeight);
    30. // For the step 4, we get the textfield's frame:
    31. if (_DateOfInvoice.isFirstResponder) {
    32. CGRect focusedTextFieldFrame = _DateOfInvoice.frame;
    33. if (!CGRectContainsRect(viewableAreaFrame, focusedTextFieldFrame)) {
    34. // We need to calculate the new Y offset point.
    35. float scrollPointY = viewHeight - keyboardHeight;
    36. // Don't forget that the scroller should go to its original position
    37. // so store the current Y point of the content offset.
    38. _originalScrollerOffsetY = _Scrolly.contentOffset.y;
    39. // Finally, scroll.
    40. [_Scrolly setContentOffset:CGPointMake(0.0, scrollPointY) animated:YES];
    41. }
    42. }
    43. if (_Notice.isFirstResponder) {
    44. CGRect noticeFrame = _Notice.frame;
    45. if (!CGRectContainsRect(viewableAreaFrame, noticeFrame)) {
    46. // We need to calculate the new Y offset point.
    47. float scrollPointY = (viewHeight + 110) - keyboardHeight;
    48. // Don't forget that the scroller should go to its original position
    49. // so store the current Y point of the content offset.
    50. _originalScrollerOffsetY = _Scrolly.contentOffset.y;
    51. // Finally, scroll.
    52. [_Scrolly setContentOffset:CGPointMake(0.0, scrollPointY) animated:YES];
    53. }
    54. }
    55. }
    56. -(void)keyboardWillHide:(NSNotification *)notification
    57. {
    58. // Move the scroll view back into its original position
    59. if (![self.Notice isFirstResponder]) {
    60. [_Scrolly setContentOffset:CGPointMake(0.0, _originalScrollerOffsetY) animated:YES];
    61. } else {
    62. [_Scrolly setContentOffset:CGPointMake(0, -50) animated:YES];
    63. }
    64. }
    Alles anzeigen
    Wenn ich diese Observer-Methoden in dem zweiten ViewController erst garnicht aktiviere funktioniert mein Zurück-Button einwandfrei.
  • Ich meinte, wo im Quelltext, da beim Zurück die App immer in der main.m mit dem Fehler
    Thread 1: EXC_BAD_ACCESS (code=1, address=0x2000000c)
    abbricht. Ich habe keinen Plan, wo sich die App zu diesem Zeitpunkt befindet.
  • Wir wissen, was Du meinst. Michael hat Dir aufgezeigt, dass Du offensichtlich das Falsche meinst.

    Exception Breakpoints werden nicht im Quelltext gesetzt, weil Du ja nie wissen kannst, an welcher Stelle Deines Quelltextes die Exception auftreten wird.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Ok, jetzt habe ich das verstanden und auch gleich ausgeführt. Ich kannte bis jetzt nur Breakpoints innerhalb des Quelltextes und hatte die Beschreibung von Apple falsch interpretiert. Leider bleibt die App nirgends hängen ausser in der main.m und diese sieht so aus :

    Quellcode

    1. #import <UIKit/UIKit.h>
    2. #import "AppDelegate.h"
    3. int main(int argc, char * argv[])
    4. {
    5. @autoreleasepool {
    6. return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    7. }
    8. }

    In der Zeile 7 mit dem Fehler aus meinem letzten Post.

    Ich habe aber jetzt durch ein bisschen Debuggen folgendes festgestellt beim Anklicken des Zurück-Buttons :
    1. Der viewWillDisappear des zweiten ViewControllers wird ausgeführt, wo ich auch den Zurück-Button angeklickt habe.
    2. Dann wird der viewWillAppear des ersten ViewControllers ausgeführt. Wenn ich dann mit Step Over weitergehe, lande ich im Assembler. Führe ich die App statt dessen weiter aus, landet der Debugger in der main.m.
    ​Das gleiche habe ich für den Aufruf des zweiten ViewControllers gemacht :
    1. Der viewWillDisappear des ersten ViewControllers wird aufgerufen und ausgeführt.
    2. Dann wird der viewWillAppear des zweiten ViewControllers ausgeführt.
    ​Könnte es eventuell daran liegen, dass ich in beiden ViewControllern die Methoden keyboardWasShown und keyboardWillHide nenne ?
  • RWarnecke schrieb:

    Dann wird der viewWillAppear des ersten ViewControllers ausgeführt. Wenn ich dann mit Step Over weitergehe, lande ich im Assembler.

    Ja, und genau da willst Du hin und herausfinden, was genau das Problem war.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • marceo schrieb:

    ggf. mal 'Zombie Objects' aktivieren im Scheme
    Dann wird dir angezeigt, wenn ein Nachricht an ein deallocated Object geschickt wird.


    'Product' -> 'Scheme' -> 'Edit Scheme' (oder 'cmd' + '<')
    Scheme
    Danke Dir marceo, das mit den Zombie Objects war genau der richtige Hinweis. Darauf hin habe ich den Fehler in folgender Methode gefunden :

    Quellcode

    1. - (void)scrollViewDidScroll:(UIScrollView *)aScrollView
    2. {
    3. // Deaktivieren des horizontalen Scrollens
    4. [aScrollView setContentOffset: CGPointMake(0, aScrollView.contentOffset.y)];
    5. }

    Damit deaktiviere ich das horizontale Scrollen in meinem UIScrollView vom ViewController 2. Das setContentOffset kann nicht mehr zugewiesen werden, da der erste ViewController schon offen ist. Wie kann ich den Aufruf dieser Methode verhindern, wenn ich den Zurück-Button anklicke ?

    Edit:
    Habe das Problem gelöst. Ich habe einfach die folgenden Zeilen hinzugefügt :

    Quellcode

    1. -(void)dealloc {
    2. self.Scrolly.delegate = nil;
    3. }
    Damit nehme ich einfach das Delegate von meinem UIScrollView in meinem zweiten View Controller. Nun funktioniert das hin und herspringen zwischen den beiden View Controller wunderbar.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RWarnecke ()