Frage zu UITableView

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

  • Frage zu UITableView

    Hallo alle zusammen,

    bin neu hier und recht neu in der iOS Entwicklung.

    Habe ein Problem mein TableView mit meinen Daten zu füllen.

    Ich habe drei NSMutableArrays, und möchte nun die Daten die in diesen gespeichert sind in die TableView schreiben. Dabei stürzt mir allerdings immer wieder der ViewController ab.

    Wen ich die Daten der drei Arrays in einem NSMutableArray hinterlegt habe und die dann ausgeben lassen klappt das ach reibungslos, nur kann ich da dann nicht drei Checkmarks setzten, sondern nur eine, was der Grund ist Warm ich diese Variante nehmen wollte.
    Bsp: wie in einem Fragebogen, wo ich eine Frage habe und man nur eine Antwort ankreuzen kann.

    Vielleicht hat ja jemand ne zündende Idee.

    Danke für eure mühen

  • -(void)viewWillAppear:(BOOL)animated {





    questArray100 = [[NSMutableArray alloc]init];

    questArray101 = [[NSMutableArray alloc]init];



    Quellcode

    1. [color=#000000] [/color][color=#6443a8]NSArray[/color][color=#000000] *Question100array = [[/color][color=#6443a8]NSArray[/color][color=#000000] [/color][color=#352380]arrayWithObjects[/color][color=#000000]:[/color]@"Keller"[color=#000000], [/color]@"Erdgeschoss"[color=#000000],[/color]@"1. Obergeschoss"[color=#000000],[/color]@"höher als 1. Obergeschoss"[color=#000000], [/color][color=#a13fa1]nil[/color][color=#000000]];[/color]
    2. [color=#6443a8]NSDictionary[/color] *Question100Dict = [[color=#6443a8]NSDictionary[/color] [color=#352380]dictionaryWithObject[/color]:Question100array [color=#352380]forKey[/color]:[color=#b54223]@"100"[/color]];
    3. [color=#6443a8]NSArray[/color] *Question101array = [[color=#6443a8]NSArray[/color] [color=#352380]arrayWithObjects[/color]:[color=#b54223]@"ja"[/color],[color=#b54223]@"nein"[/color],[color=#a13fa1]nil[/color]];
    4. [color=#6443a8]NSDictionary[/color] *Question101Dict = [[color=#6443a8]NSDictionary[/color] [color=#352380]dictionaryWithObject[/color]:Question101array [color=#352380]forKey[/color]:[color=#b54223]@"101"[/color]];
    5. [[color=#607f87]questArray100[/color] [color=#352380]addObject[/color]:Question100Dict];
    6. [[color=#607f87]questArray101[/color] [color=#352380]addObject[/color]:Question101Dict];
    Alles anzeigen



    Diese Beiden Array möchte ich gerne ausgeben.


    Falls noch Fragen nach speziellen code teilen sind stelle ich die Geren auch online.


  • Also das Ziel ist es, dass man einen Fragenkatalog erhält, den mann beantworten muss.
    Hierfür wollte ich jede Frage mit ihren Antworten als ein Array darstellen, und diese als teil eines Übergeordneten Arrays, welches einem Fragebogen entspricht.


    #import "KatastrophenViewController2.h"

    @implementation KatastrophenViewController2

    @synthesize katastrophen;
    @synthesize lastIndexPath;

    -(void)viewWillAppear:(BOOL)animated {


    questArray100 = [[NSMutableArray alloc]init];
    questArray101 = [[NSMutableArray alloc]init];

    NSArray *Question100array = [NSArray arrayWithObjects:@"Keller", @"Erdgeschoss",@"1. Obergeschoss",@"höher als 1. Obergeschoss", nil];
    NSDictionary *Question100Dict = [NSDictionary dictionaryWithObject:Question100array forKey:@"100"];

    NSArray *Question101array = [NSArray arrayWithObjects:@"ja",@"nein",nil];
    NSDictionary *Question101Dict = [NSDictionary dictionaryWithObject:Question101array forKey:@"101"];

    [questArray100 addObject:Question100Dict];
    [questArray101 addObject:Question101Dict];

    NSLog(@"Länge des Arrays: %i", [questArray100 count]);

    self.navigationItem.title = katastrophen.katastrophe;

    }

    #pragma mark -
    #pragma mark Table view data source

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return [questArray100 count];
    }


    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    NSDictionary *dictionary100 = [questArray100 objectAtIndex:section];
    NSArray *array100 =[dictionary100 objectForKey:@"100"];
    return [array100 count];
    }
    - (NSInteger *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    return @"In welcher Etage befinden sie sich?";
    }


    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }


    NSDictionary *dictionary100 = [questArray100 objectAtIndex:indexPath.section];
    NSArray *array100 = [dictionary100 objectForKey:@"100"];
    NSString *cellValue100 = [array100 objectAtIndex:indexPath.row];
    cell.textLabel.text = cellValue100;

    return cell;
    }

    #pragma mark -
    #pragma mark Table view delegate

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSDictionary *dictionary = [questArray100 objectAtIndex:indexPath.section];
    NSArray *array = [dictionary objectForKey:@"100"];
    NSString *selectedCountry = [array objectAtIndex:indexPath.row];
    int ArrayValue = 0;

    NSLog(@"Länge des Arrays: %i", [array count]);
    for (int i = 0; i < [array count]; i++) {
    //NSLog(@"Eintrag an Position %i: %@", i,[questArray100 objectAtIndex:i]);
    if (selectedCountry == [array objectAtIndex:i]){
    ArrayValue = i;
    NSLog(@"Eintrag an Position %i", ArrayValue);
    }
    }

    //Initialize the detail view controller and display it.


    int newRow = [indexPath row];
    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;

    if (newRow != oldRow)
    {
    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
    indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;

    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:
    lastIndexPath];
    oldCell.accessoryType = UITableViewCellAccessoryNone;
    lastIndexPath = indexPath;
    }

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    }


    #pragma mark -
    #pragma mark Memory management

    - (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc. that aren't in use.
    }

    - (void)viewDidUnload {

    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
    }

    - (void)dealloc {
    [questArray100 release];
    [questArray101 release];
    [super dealloc];
    }

    @end


    Wenn ich nun aber in numberOfRowsInSection und cellForRowAtIndeyPath das was mit questArray100 funktioniert noch für questArray101 hinzufüge stürzt das Programm mit dem Fehler:
    terminate called after throwing an instance of 'NSException'
    ab.
  • Sorry,
    Fehler:

    2011-07-15 09:17:05.644 Massdamage[989:207] Länge des Arrays: 1

    2011-07-15 09:17:05.649 Massdamage[989:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

    *** Call stack at first throw:

    (

    0 CoreFoundation 0x00e435a9 __exceptionPreprocess + 185

    1 libobjc.A.dylib 0x00f97313 objc_exception_throw + 44

    2 CoreFoundation 0x00e391cc -[__NSArrayI objectAtIndex:] + 236

    3 Massdamage 0x000033cf -[KatastrophenViewController2 tableView:cellForRowAtIndexPath:] + 557

    4 UIKit 0x00330b98 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634

    5 UIKit 0x003264cc -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75

    6 UIKit 0x0033b8cc -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561

    7 UIKit 0x0033390c -[UITableView layoutSubviews] + 242

    8 QuartzCore 0x01de3a5a -[CALayer layoutSublayers] + 181

    9 QuartzCore 0x01de5ddc CALayerLayoutIfNeeded + 220

    10 QuartzCore 0x01d8b0b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310

    11 QuartzCore 0x01d8c294 _ZN2CA11Transaction6commitEv + 292

    12 QuartzCore 0x01d8c46d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99

    13 CoreFoundation 0x00e2489b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27

    14 CoreFoundation 0x00db96e7 __CFRunLoopDoObservers + 295

    15 CoreFoundation 0x00d821d7 __CFRunLoopRun + 1575

    16 CoreFoundation 0x00d81840 CFRunLoopRunSpecific + 208

    17 CoreFoundation 0x00d81761 CFRunLoopRunInMode + 97

    18 GraphicsServices 0x0179a1c4 GSEventRunModal + 217

    19 GraphicsServices 0x0179a289 GSEventRun + 115

    20 UIKit 0x002c9c93 UIApplicationMain + 1160

    21 Massdamage 0x00001cd0 main + 102

    22 Massdamage 0x00001c61 start + 53

    )

    terminate called after throwing an instance of 'NSException'

  • naja es fängt schon damit an, dass Du mal so gar keine Ahnung vom Memory Management hast.

    Du allozierst deine Arrays in jedem viewWillAppear neu, released sie aber nur im dealloc. Da kannst du quasi zusehen wie der Speicher immer weniger wird.

    Und wenn Du nur 1 Item in das Array schreibst, versuchst aber 2 auszulesen, dann bekommst du genau diese Fehlermeldung

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Nein, wenn du die Arrays in viewWill Appear erzeugst, dann solltest Du sie auch in viewWillDisappear freigeben. Sinn macht das allersinge keinen wenn es sich eh um statische ARrays handelt. Dann solltest Du sie tatsächlich in viewDidLoad erzeugen und in viewDidUnload releasen.

    Sorry, ich habe mich verguckt. Du hast 2 Items in dem Array, es wird aber auf das dritte zugegriffen. Ich würde mal einen Breakpoint setzten und dann step bei step durchgehen. Dann siehst du sofort wo der Index 2 (also das dritte Element) ist.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • fatmann09 schrieb:

    also wäre hier der richtige Schritt die Arrays im viewdidunload zu releasen?! Den Zweiten teil der Antwort verstehe ich leider nicht! Ich habe doch zwei NSDictionary Elemente. die ich ach beide ausgeben will beide haben natürlich nur ein Element, das jeweilige Array.


    nein viewdidunload wird nur aufgerufen wenn die view ganz verschwindet (also aus den speicher) das gegenstück dazu ist viewDidLoad
    was du benutzen müstest wäre viewWillDisappear das wird jedesmal aufgerufen sobald die view nicht mehr sichtbar ist und andersrum viewWillAppear wird jedesmal aufgerufen wenn die view sichtbar wird!

    kleiner tipp:
    init -> dealloc
    didLoad -> didUnload
    willAppear -> willDisappear

    wenn du was in init erzeugst solltest du es in dealloc zerstören bei didLoad in didUnload ... usw ;)
    俺の世界にようこそ
  • danke für die Ratschläge, ach wenn ich das anzeige Problem erst einmal gelöst habe, stehe ich nun vor dem nächsten, wieso ich das überhabt so umständlich gemacht habe. Jedes mal wen ich nun eine Checkmark setze verschwindet die vorherige, das ist ja nicht so schlimm, solange das innerhalb des einzelnen ArrayspPassiert, doch leider löscht er auch di,e die in dem zweiten Array sind, wen ich eine imErsten setzte, bzw. umgekehrt. Da ich leider mein Verständnis dieser Methode noch nicht tiefgreifend genug ist. Ist nun die Frage ob das eine Eigenheit dieses Checkmark ist, oder ob das nur ein "Anfängerfehler ist".

    Der Code von didSelectedRowAtIndexPath sieht wie folgt aus:

    Quellcode

    1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    2. if(indexPath.section == 0) {
    3. NSDictionary *dictionary100 = [questArray100 objectAtIndex:indexPath.section];
    4. NSArray *array100 = [dictionary100 objectForKey:@"100"];
    5. NSString *selectedAnswer = [array100 objectAtIndex:indexPath.row];
    6. int ArrayValue = 0;
    7. NSLog(@"Länge des Arrays: %i", [array100 count]);
    8. for (int i = 0; i < [array100 count]; i++) {
    9. //NSLog(@"Eintrag an Position %i: %@", i,[questArray100 objectAtIndex:i]);
    10. if (selectedAnswer == [array100 objectAtIndex:i]){
    11. ArrayValue = i;
    12. NSLog(@"Eintrag an Position %i", ArrayValue);
    13. }
    14. }
    15. }
    16. else {
    17. NSDictionary *dictionary101 = [questArray101 objectAtIndex:0];
    18. NSArray *array101 = [dictionary101 objectForKey:@"101"];
    19. NSString *selectedAnswer = [array101 objectAtIndex:indexPath.row];
    20. int ArrayValue = 0;
    21. NSLog(@"Länge des Arrays: %i", [array101 count]);
    22. for (int i = 0; i < [array101 count]; i++) {
    23. //NSLog(@"Eintrag an Position %i: %@", i,[questArray100 objectAtIndex:i]);
    24. if (selectedAnswer == [array101 objectAtIndex:i]){
    25. ArrayValue = i;
    26. NSLog(@"Eintrag an Position %i", ArrayValue);
    27. }
    28. }
    29. }
    30. int newRow = [indexPath row];
    31. int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
    32. if (newRow != oldRow)
    33. {
    34. UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
    35. newCell.accessoryType = UITableViewCellAccessoryCheckmark;
    36. UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
    37. oldCell.accessoryType = UITableViewCellAccessoryNone;
    38. lastIndexPath = indexPath;
    39. }
    40. [tableView deselectRowAtIndexPath:indexPath animated:YES];
    41. }
    Alles anzeigen
  • Du holst Dir einen String aus dem Array über seine Position, nur um dann das Arrey noch einmal in einer Schleife zu durchlaufen und jeden String im Array mit dem geholten Array zu vergleichen um die Position zu ermitteln ???? Irgendwie solltest Du da echt mal drüber nachdenken. Ausserdem vergleicht man strings nicht mit ==

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • fatmann09 schrieb:

    ja das mit dem String vergleich hab ich mittlerweile dann ach mal herausgefunden. Naja ich muss die vergleichen, damit ich den index bekomme, der hinterher in ner Datenbank abgelegt werden soll! Deshalb durchsuche ich das!


    Das ist blödsinn

    Was fällt Dir auf ?

    Quellcode

    1. NSString *selectedAnswer = [array100 objectAtIndex:indexPath.row];
    2. if (selectedAnswer == [array100 objectAtIndex:i])
    3. {
    4. }


    i wird immer = indexPath. row sein, vorrausgesetzt du hast nicht zwei gleiche Einträge im Array, was ich aber nicht glaube.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)