uiswitch in uitableviewcell

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

  • uiswitch in uitableviewcell

    Abend Community,

    ich steh mal wieder auf dem Schlauch -.-
    Ich habe eine Tableview, die ich mit JSON Daten von einem Webservice füttere. Die Anzahl der Werte in der Tabelle sind somit dynamisch.
    Ich habe jetzt ein UISwitch in jede Zelle des Tableviews gebaut. Wie kann ich aber auf jedes einzelne uiswitch reagieren?
    Im Grunde genommen, habe ich ja nur ein Switch erstellt, aber es in allen Cell's platziert!
    Gibt es eine andere Möglichkeit?

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. static NSString *CellIdentifier = @"structureCell";
    4. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    5. if (cell == nil) {
    6. cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    7. //add a switch
    8. inTableSwitch = [[UISwitch alloc] init];
    9. cell.accessoryView = inTableSwitch;
    10. }
    11. // Configure the cell...
    12. NSDictionary *cellValue = [structureArray objectAtIndex:indexPath.row];
    13. cell.textLabel.text = [cellValue objectForKey:@"STRUCTURE_NAME"];
    14. return cell;
    15. }
    Alles anzeigen


    Gruß aus Bayern :)
    lernen, lernen, lernen :)
  • Delegate des TableViews, wenn du die Switches denn wirklich als Accessory View angelegt hast.
    developer.apple.com/library/io…appedForRowWithIndexPath:
    «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
  • Ich gebe beim Erstellen der Zellen jedem Switch ein Tag mit:

    Quellcode

    1. [...]
    2. UISwitch *optionSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(1.0, 1.0, 20.0, 20.0)];
    3. [optionSwitch setOn:switchState];
    4. [optionSwitch setTag:index];
    5. [optionSwitch addTarget:self action:@selector(toggleViewOption:) forControlEvents:(UIControlEventValueChanged | UIControlEventTouchDragInside)];
    6. [cell setAccessoryView:optionSwitch];
    7. [...]

    Dann kann ich in "toggleViewOption" dieses Tag einfach abfragen und entsprechend reagieren, z. B. zum Setzen von Defaults auf Basis eines NSString-Arrays menuKeys:

    Quellcode

    1. [...]
    2. BOOL switchState = [sender isOn];
    3. NSString *defaultsKey = [menuKeys objectAtIndex:[sender tag]];
    4. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    5. [defaults setObject:[NSNumber numberWithBool:switchState] forKey:defaultsKey];
    6. [...]

    HTH, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Hi Mattes,

    einen derartigen Ansatz habe ich zunächst auch im Kopf gehabt.
    Als Delegating-Freund habe ich den jedoch gleich wieder verworfen.

    - (void)tableView: (UITableView *)tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *)indexPath
    liefert ja freundlicherweise einen Indexpath mit, so dass man sich nicht über den Tag hangeln muss - man sieht ja gleich, aus welcher Reihe die Aktion ausgeführt wurde.

    Allerdings funktioniert das nur bei Controls. Wurde dem accessoryView ein einfaches View zugefügt, dann wird diese Delegate-Methode nicht aufgerufen.

    Ich bin mir nur nicht sicher, ob dort der Status des UISwitch auch geändert wird. Vermutlich dient dieser nur zur Anzeige und man muss dann in der Delegate-Methode den angezeigten Wert umstellen.

    Wie meinte schon Larray -Wall?
    "There's more than one way to do it."
    But sometimes consistency is not a bad thing either. ;)
    «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
  • Lucas de Vil schrieb:

    - (void)tableView: (UITableView *)tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *)indexPath
    liefert ja freundlicherweise einen Indexpath mit, so dass man sich nicht über den Tag hangeln muss - man sieht ja gleich, aus welcher Reihe die Aktion ausgeführt wurde.

    Stimmt, das ist eigentlich eleganter. Gibt es eine Möglichkeit, bei mehreren Section in einer UITableView über den indexPath einen fortlaufenden Index zu bekommen, mit dem man dann in ein Array greifen könnte? Ich habe bei mir nämlich die Bezeichnungen und die entsprechenden defaults-Schlüssel in Arrays liegen, für deren Zugriff ich den Tag nutze ... also ich meine natürlich, ohne händisch durch die Sections zu gehen und deren Einträge zu zählen :D

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ich kann grad mit "Ich habe bei mir nämlich die Bezeichnungen und die entsprechenden defaults-Schlüssel in Arrays liegen, für deren Zugriff ich den Tag nutze" nicht allzuviel anfangen.
    Also ein Aufbau gemäß folgendem Pseudo-Code?

    Quellcode

    1. (
    2. Section 1;
    3. Item 1;
    4. Item 2;
    5. Item 3;
    6. Item 4;
    7. Section 2;
    8. Item 5;
    9. Item 6;
    10. Section 3;
    11. Item 7;
    12. Item 8;
    13. Item 9;
    14. )
    Alles anzeigen

    Das ist, wenn ich das richtig verstanden habe, irgendwie nicht der Plan der verschachtelten Arraystruktur und damit des NSIndexSets sowie den Sections.
    Ich meine, wie kommst du denn da an die Anzahl deiner Sections und die Anzahl der Rows einer Section?

    Korrekt fühlt sich eher Folgendes an:

    Quellcode

    1. (
    2. (
    3. Item 1;
    4. Item 2;
    5. Item 3;
    6. Item 4;
    7. )
    8. (
    9. item 5;
    10. item 6;
    11. )
    12. (
    13. item 7;
    14. item 8;
    15. item 9;
    16. )
    17. )
    Alles anzeigen


    Jetzt ist es relativ simpel:

    C-Quellcode

    1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    2. {
    3. return [array count];
    4. }
    5. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    6. {
    7. return [[array objectAtIndex:section] count];
    8. }

    Und so stellt sich auch die Frage nach dem fortlaufenden Index nicht mehr.
    Wie machst du das denn genau?
    «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

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Lucas de Vil ()

  • Lucas de Vil schrieb:

    Ich kann grad mit "Ich habe bei mir nämlich die Bezeichnungen und die entsprechenden defaults-Schlüssel in Arrays liegen, für deren Zugriff ich den Tag nutze" nicht allzuviel anfangen.
    Also ein Aufbau gemäß folgendem Pseudo-Code?

    Ich will jetzt zwar nicht den Thread hijacken, aber trotzdem zur Erklärung (und in der Hoffnung auf eine elegantere Lösung): In meiner UITableView werden mit UISwitches Preferences gesetzt (was für'n Denglisch). Ich habe zwei Arrays, im einen liegen die Titel der Schalter (nicht die Überschriften der Abschnitte), in dem anderen die Variablennamen, mit denen die Einstellungen in den User-Defaults gespeichert werden. Also analog zu Deinem "Pseudocode" einfach nur:

    Quellcode

    1. (
    2. Item 1;
    3. Item 2;
    4. Item 3;
    5. Item 4;
    6. Item 5;
    7. Item 6;
    8. Item 7;
    9. Item 8;
    10. Item 9;
    11. )
    Alles anzeigen

    Wenn ich nun über die von Dir genannte Delegate-Methode und den Properties auf meine Vektorelemente zugreifen wollte, müsste ich erst einmal ermitteln, welchen Index der betätigte Schalter hat. Also eine Schleife über die Sections laufen lassen und je Section die Anzahl der enthaltenen Zeilen aufaddieren. Kein Ding, mich hätte nur interessiert, ob es hierzu für einen gegebenen NSIndexPath nicht etwas Eleganteres gibt... Klar, man kann in Schönheit sterben, aber wenn ich mich mal von der zitierten "Tag"-Lösung verabschiede, dann doch auch richtig :)

    Mattes

    P.S.: Die Umstrukturierung des "flachen" Arrays in ein verschachteltes kommt dieser Lösung schon sehr nahe. Bleibt nur die Frage, ob man grundsätzlich aus Section + Row eine fortlaufende Nummer ermitteln kann, ohne die o. g. Schleifen-Lösung zu verwenden...
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ah, das heißt, du holst dir aus Array [descriptions objectAtIndex:index] den Titel für die Knöppe und aus Array [keys objectAtIndex:index] die dazugehörigen Schlüssel für die User Defaults.
    Stell ich mir kompliziert in der Umsetzung mit Rows und Sections vor. Nun gut.

    MyMattes schrieb:

    Bleibt nur die Frage, ob man grundsätzlich aus Section + Row eine fortlaufende Nummer ermitteln kann, ohne die o. g. Schleifen-Lösung zu verwenden...

    Nein. Der Ansatz des IndexPath ist der, dass man sich nicht um irgendwelche vorgelagerten Arraystrukturen kümmern muss. Ergo kann man das auch nicht.
    Man muss da also von Hand durch.

    Was spricht gegen ein Array von Dictionaries?

    Quellcode

    1. (
    2. {
    3. @"Title", @"Explode"
    4. @"Value", @"myApplicationDeviceShouldExplodeAfter10Minutes"
    5. }
    6. {
    7. @"Title", @"Smoke"
    8. @"Value", @"myApplicationDeviceShouldThrowALotOfSmog"
    9. }
    10. {
    11. @"Title", @"Implode"
    12. @"Value", @"myApplicationDeviceShouldImplodeAtNextStart"
    13. }
    14. )
    Alles anzeigen


    So kommst du dann via [[actions objectAtIndex:indexPath.row] valueForKey:@"Title"] an den Titel bzw. via @"Value" an den Wert.

    Das Ganze kannst du dann natürlich gemäß den Sections in unterschiedliche Unterarrays aufsplitten.

    Quellcode

    1. (
    2. (
    3. {
    4. @"Title", @"Explode"
    5. @"Value", @"myApplicationDeviceShouldExplodeAfter10Minutes"
    6. }
    7. {
    8. @"Title", @"Implode"
    9. @"Value", @"myApplicationDeviceShouldImplodeAtNextStart"
    10. }
    11. )
    12. (
    13. {
    14. @"Title", @"Smoke"
    15. @"Value", @"myApplicationDeviceShouldThrowALotOfSmog"
    16. }
    17. )
    18. )
    Alles anzeigen

    Nu kannste beispielsweise sagen:

    C-Quellcode

    1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    2. {
    3. return [array count];
    4. }
    5. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    6. {
    7. return [[array objectAtIndex:section] count];
    8. }
    9. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    10. {
    11. CGFloat tableViewWidth = [tableView frame].size.width;
    12. UILabel * header = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 20.0, tableViewWidth)];
    13. switch(section)
    14. {
    15. case 0:
    16. [header setText:@"Destruction"];
    17. break;
    18. case 1:
    19. [header setText:@"Visual Effects"];
    20. break;
    21. }
    22. return header;
    23. }
    24. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    25. {
    26. NSString *CellIdentifier = @"Cell";
    27. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    28. if(cell == nil)
    29. {
    30. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    31. }
    32. NSDictionary * dict = [[array objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    33. [[cell textLabel] setText:[dict valueForKey:@"Title"]];
    34. [[cell detailTextLabel] setText:[dict valueForKey:@"Value"]];
    35. return cell;
    36. }
    37. - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
    38. {
    39. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    40. NSString * currentKey = [[[array objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] valueForKey:@"value"];
    41. bool currentState = [[defaults objectForKey:currentKey] boolValue];
    42. [defaults setObject:[NSNumber numberWithBool:!currentState] forKey:currentKey];
    43. }
    Alles anzeigen


    Objektgraphen fetzen einfach. ;)

    .oO(Hey, nach all dem Rumgehampel hab ich endlich nen Lösungsansatz für mein Modellierungsproblem. Danke! :))
    «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
  • Lucas de Vil schrieb:

    Objektgraphen fetzen einfach. ;)

    Coole Idee, die gefällt mir: Beim Initialisieren einfach zwei geschachtelte Arrays mit Dictionaries, und die ganze Rumrechnerei löst sich in Wohlgefallen auf: Das werde ich für's nächste minor release einbauen ... you made my day!

    Lucas de Vil schrieb:

    .oO(Hey, nach all dem Rumgehampel hab ich endlich nen Lösungsansatz für mein Modellierungsproblem. Danke! :))

    Da nicht für ... :)

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.