2009-07-28 14 views
18

Kennt jemand eine Möglichkeit, das Erscheinungsbild des stringbasierten UISegmentedControl anzupassen? Ich versuche, die Hintergrundfarbe der Zelle und die Textfarbe unterschiedlich abhängig von dem ausgewählten Status des Elements festzulegen.Anpassen der Farben eines UISegmentedControls

Oder kennen Sie eine Möglichkeit, UIImagages on the fly zu erstellen, in denen benutzerdefinierte Zeichenfolgen eingeschlossen werden? (z. B. uiimage mit weißem Hintergrund erstellen, Text überlagern, zur segmentierten Steuerung hinzufügen).

Ich weiß, dass Sie nur Zeichenketten oder Bilder in der segmentierten Steuer ...

Prost haben!

Antwort

17

UISegmentedControl hat eine tintColor Eigenschaft - das können Sie ändern, welche Farbe die Kontrolle, aber nicht die allgemeine „Stil“ (die abgerundete, abgeschrägte Form):

segmentedControl.tintColor = [UIColor blueColor]; 

Was UIImages auf die Schaffung fliegen, können Sie eine CGContext schaffen, tun, was Zeichnung, die Sie brauchen, um in diesem Zusammenhang (einschließlich Strings) und dann eine UIImage erhalten aus dem Kontext des CGImage:

CGContextRef drawContext = CGBitmapContextCreate(<many parameters>); 
//do drawing here 
CGImageRef finalImage = CGBitmapContextCreateImage(drawContext); 
UIImage *cellImage = [UIImage finalImage]; 
10
segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f blue:0.61176f alpha:1.0f]; 

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; 
9

Alles, was Sie tun müssen, ist:

// Get an array of the subviews of a UISegmentedControl, for example myUISegmentedControl: 

NSArray *arri = [myUISegmentedControl subviews]; 

// Change the tintColor of each subview within the array: 

[[arri objectAtIndex:0] setTintColor:[UIColor redColor]]; 

[[arri objectAtIndex:1] setTintColor:[UIColor greenColor]]; 
+0

funktioniert nicht für mich ändern wollen –

+1

Arbeitete perfekt auf iOS 7 ... du bist unglaublich! – CommaToast

+1

Gute Sachen nette Lösung – DogCoffee

7

Die meisten der hier Antworten beantworten nicht die spezifische Frage, wie auf ausgewählten Zustand eine Schaltfläche Farbe einzustellen basiert, die eine andere Farbe bedeutet, ist für nicht-ausgewählten Zustand gewünscht. Ich habe lange damit gerungen und wollte meine Lösung für andere nutzen. In meinem Beispiel wird ein UISegmentedControl mit drei Segmenten verwendet. Die nicht ausgewählte Farbe für alle drei sollte gleich sein, um ein einheitliches Aussehen zu erhalten. Der ausgewählte Status für das erste und letzte Segment hat eindeutige Farben.

enter image description here

Das Problem ist, dass die segmentierte Kontrolle nicht in der gleichen Reihenfolge sein, ist garantiert, so dass die Farben, wie Sie und her wählen zurück gemischt. Dan hat eine Lösung veröffentlicht, die Tags verwendet, aber leider funktioniert es nicht mehr für iOS 6 und höher.

Der größte Teil dieses Codes stammt aus this post. Ich habe es leicht geändert, um einzigartige ausgewählte Farben zu haben.

Was es Arbeit macht, ist die Sortierung aber nehmen diese zwei wichtigen Linien für die gewählte Farbeinstellung:

NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex; 
[[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]]; 

- (void) updateSegmentColors 
{ 
    UIColor *checkColor = [UIColor colorWithRed: 29/255.0 green:166/255.0 blue:47/255.0 alpha:1.0]; 
    NSArray *segmentColors = [[NSArray alloc] initWithObjects:checkColor, [UIColor blueColor], [UIColor redColor], nil]; 

    UISegmentedControl *betterSegmentedControl = self.StatusControl; 

    // Get number of segments 
    NSUInteger numSegments = [betterSegmentedControl.subviews count]; 

    // Reset segment's color (non selected color) 
    for(int i = 0; i < numSegments; i++) { 
     // reset color 
     [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:nil]; 
     [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:[UIColor blueColor]]; 
    } 

    // Sort segments from left to right 
    NSArray *sortedViews = [betterSegmentedControl.subviews sortedArrayUsingFunction:compareViewsByOrigin context:NULL]; 

    // Change color of selected segment 
    NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex; 
    [[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]]; 

    // Remove all original segments from the control 
    for (id view in betterSegmentedControl.subviews) { 
     [view removeFromSuperview]; 
    } 

    // Append sorted and colored segments to the control 
    for (id view in sortedViews) { 
     [betterSegmentedControl addSubview:view]; 
    } 
} 


NSInteger static compareViewsByOrigin(id sp1, id sp2, void *context) 
{ 
    // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects. 
    float v1 = ((UIView *)sp1).frame.origin.x; 
    float v2 = ((UIView *)sp2).frame.origin.x; 
    if (v1 < v2) 
     return NSOrderedAscending; 
    else if (v1 > v2) 
     return NSOrderedDescending; 
    else 
     return NSOrderedSame; 
} 

ich den Code platziert in einem eigenen Verfahren wegen Ich lade diese segmentierten Steuerelemente in einer Tabellenansicht und muss sie beim Laden ausführen (vorhandene Status aus dem Speicher) und wenn ein Benutzer eine Auswahl ändert. Jetzt muss ich nur [Self updateSegmentColors]; aufrufen, wenn sich etwas ändert.

1

Ich konnte es über Interface Builder in XCode 6 tun.Beigefügt ist die Tönung Eigenschaft:

enter image description here

6

Der beste Weg, die ich gefunden habe, so etwas wie dies zu tun setzt verschiedene Attribute für unterschiedliche UIControlStates auf der segmentierten Kontrolle.

self.segmentedControl.tintColor = [UIColor cb_Grey1Color]; 
self.segmentedControl.backgroundColor = [UIColor cb_Grey3Color]; 
NSDictionary *selectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
            [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName, 
            [UIColor whiteColor], NSForegroundColorAttributeName, 
            [UIColor cb_Grey1Color], NSBackgroundColorAttributeName, nil]; 
[self.segmentedControl setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected]; 
NSDictionary *unselectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
             [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName, 
             [UIColor cb_Grey2Color], NSForegroundColorAttributeName, 
             [UIColor cb_Grey3Color], NSBackgroundColorAttributeName, nil]; 
[self.segmentedControl setTitleTextAttributes:unselectedAttributes forState:UIControlStateNormal]; 
+0

BackgroundColorAttribute ändert nur den Hintergrund des Titels –

2

Hier ist ein Beispielcode, der mit iOS9 funktioniert, aber es ist ein Hack, und die Arbeit möglicherweise nicht in späteren Versionen:

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Title1", @"Title2"]]; 
for (id segment in [segmentedControl subviews]) 
{ 
    for (id view in [segment subviews]) 
    { 
     NSString *desc = [view description]; 
     if ([desc containsString:@"UISegmentLabel"]) 
     { 
      [segment setTintColor:([desc containsString:@"Title1"] ? [UIColor blueColor] : [UIColor greenColor])]; 
     } 
    } 
} 
0

ich etwas Ähnliches erreichen wollte - die Hintergrundfarbe von das ausgewählte Segment zu einer Farbe, während die "Kontur" der übrigen Segmente eine andere Farbe hatte. Die Idee besteht darin, das UISegmentedControl zu unterklassifizieren und 2 Methoden zu überschreiben, um sowohl den Anfangszustand zu formatieren als auch das Änderungsereignis zu erfassen, um es automatisch zu formatieren, wenn der Benutzer verschiedene Segmente auswählt.

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    [self updateSegmentColors]; 
} 
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    [self updateSegmentColors]; 
} 
- (void)updateSegmentColors { 
    NSArray* segments = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { 
     // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects. 
     float v1 = ((UIView *)obj1).frame.origin.x; 
     float v2 = ((UIView *)obj2).frame.origin.x; 
     if (v1 < v2) return NSOrderedAscending; 
     else if (v1 > v2) return NSOrderedDescending; 
     else return NSOrderedSame; 
    }]; 
    for (int i=0; i<segments.count; i++) { 
     if (i == self.selectedSegmentIndex) { 
      [segments[i] setTintColor:[UIColor redColor]]; 
     } else { 
      [segments[i] setTintColor:[UIColor grayColor]]; 
     } 
    } 
} 
0

Schriftfarbe swift 3 und schnelle 4, wenn Sie

für nicht ausgewählte Artikel

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .normal) 

für ausgewählte Artikel

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .selected) 
Verwandte Themen