Elemente eines NSSegmentedControl ändern

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

  • Elemente eines NSSegmentedControl ändern

    Hallo zusammen!

    Ich möchte zur Laufzeit per Code die Elemente eines NSSegmentedControl ändern. Allerdings erzeuge ich das Control nicht mit Code sondern aus dem Interface Builder heraus.

    Die Werte für die Titel der Segmente stammen per NSMutableArray aus einer Datenbank (das funktioniert auch korrekt, hab ich per NSRunAlertPanel getestet). In der Doku stehen exakt dieselben Methodenaufrufe für das Hinzufügen von Segmenten zur Laufzeit. Trotzdem ändert sich das Control bei einem Lauf nicht bzw. zeigt immer noch das Aussehen (Anzahl der Segmente, Beschriftung) wie im Interface Builder.

    Das ist das Codestück, das die Segmente ändern soll:

    Quellcode

    1. [buttonBar setSegmentCount:[effects count]];
    2. for (i = 0; i < [effects count]; i++) {
    3. [buttonBar setLabel:[[effects objectAtIndex:i] objectForKey:@"name"] forSegment:i];
    4. [buttonBar setWidth:0 forSegment:i];
    5. }


    Ich hoffe, mir kann jemand helfen.


    Gruß,

    vbinsider
  • Wie Tom911 schon festgestellt hat: Dein "buttonBar" ist als 'IBOutlet' nicht verbunden, also von der Instanz, in der Dein Code liegt, zu dem 'Control' im IB.
    Effektiv ziehst Du 2 Verbindungen/
    Ansonsten:

    Quellcode

    1. NSLog([buttonBar description]);
    ist aussagekräftiger.
    I would be embarrassed if they did not spy on me.
  • Wobei man den NSLog() nicht so machen sollte: Wenn sich in der Description ein % befindet, geht das übel in die Hose. Außerdem entscheidet NSLog() selbst, welche Methode es zum Dump aufruft. Daher noch besser:

    Quellcode

    1. NSLog( @"%@", buttonBar );
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Problem gefunden! Vielen Dank an euch alle!

    Die Funktion zum Laden der Segmente aus der Datenbank wurde zu früh aufgerufen (nämlich im Konstruktor des Controllers). Scheinbar sind die Outlets da noch nicht miteinander verbunden. Ein späterer per IdleTimer ausgelöster Aufruf der Funktion zeigte nämlich statt (null) im Log ein vorhandenes NSSegmentedControl an. Ich hab den Aufruf in die Methode awakeFromNib() verschoben, dann verschwindet der (null)-Eintrag am Anfang.

    Seltsam ist nur, dass das Verschicken von Messages an nicht existierende Objekte in ObjC zulässig ist, C++ hätte da mit Sicherheit anders reagiert.


    Gruß,

    vbinsider
  • Bei mir ist das ein Controllerobjekt, das eine Datenbankverbindung verwaltet und per IBOutlet an das NSSegmentedControl in meinem Hauptfenster gekoppelt ist.

    Es ging letztlich ja nur darum, festzustellen, wann die Kopplung verfügbar ist. Im Konstruktor ist sie das offenbar nicht. In der awakeFromNib() schon.

    Da es sich um Zeiger handelt, stellt sich doch das Problem der wechselseitigen Verweise gar nicht, anders als bei wechselseitigen Verweisen von z.B. Klassen in C++ (Stichwort Forward-Deklaration). Aber hier hab ich das doch nicht, weil das Programm die Bindung erst zur Laufzeit erzeugt.
  • Es kann nicht im -init vorhanden sein, weil es Fälle gibt, in denen das gar nicht geht.

    Da es sich um Zeiger handelt, stellt sich doch das Problem der wechselseitigen Verweise gar nicht,

    Beispiel:
    A verweist auf B.
    B verweist auf A.

    Wann wird A initialisiert, wann B? Wann werden die Verweise gesetzt?

    "Unmögliches erledigen wir sofort, Wunder dauern etwas länger."

    (Mal ganz abgesehen davon, dass ich jeden Loader standrechtlich erschießen würde, der mir einen Verweis *vor* der Initialisierung setzt.)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von vbinsider
    Seltsam ist nur, dass das Verschicken von Messages an nicht existierende Objekte in ObjC zulässig ist, C++ hätte da mit Sicherheit anders reagiert.


    Nachrichten an "dangling pointers" quittiert Objective-C genau wie C++ mit ernsten Problemen, Nachrichten an einen NIL-pointer sind hingegen erlaubt und das ist auch ziemlich praktisch so.

    ciao

    gandhi
  • Original von vbinsider
    Es ging letztlich ja nur darum, festzustellen, wann die Kopplung verfügbar ist. Im Konstruktor ist sie das offenbar nicht. In der awakeFromNib() schon.

    Wenn man den IB benutzt, wäre die Lektüre der Dockumentation speziell zu 'awakeFromNib:' schon angebracht, bevor man irgendwelche Theorien entwickelt.
    I would be embarrassed if they did not spy on me.