2015-03-28 16 views
6

A partire da imparare Swift e sto cercando di convertire questo codice ObjectiveC:Come impostare UISegmentedControl Tinta per singolo segmento

[[mySegmentedControl.subviews objectAtIndex:0] setTintColor:[UIColor blueColor]] 

Questa imposta correttamente il colore della tinta del primo segmento.


Questo è il più vicino Sono venuto a ottenere una versione Swift dello stesso codice:

mySegmentedControl?.subviews[0].tintColor = UIColor.blueColor() 

L'errore che ottengo è '@Ivalue $T9' is not identical to 'UIColor!!'


non capisco cosa significa questo errore. Quando guardo il metodo .tintColor elenca UIColor!? e non ho ancora trovato quello che lo !? insieme significa ancora in Swift.

+0

Se mySegmentedControl un IBOutlet? Se lo è, dichiaralo @IBOutlet var mySegmentedControl = UISegmentedControl! Allora non hai bisogno del? operatore. Questo non risolverà l'intero problema, ma questa è una cosa. Se le sottoview [0] possono restituire nil, allora è un optional, quindi magari metti un! dopo [0]. – clearlight

risposta

16

Questo risolverà il vostro problema:

var subViewOfSegment: UIView = mySegmentedControl.subviews[0] as UIView 
subViewOfSegment.tintColor = UIColor.blueColor() 

È inoltre possibile

(mySegmentedControl.subviews[0] as UIView).tintColor = UIColor .blueColor() 
+0

E 'stato! Grazie per l'aiuto. –

+0

È documentato? – igrek

0

Per cambiare il tintColor del segmento selezionato

Utilizzare il valore evento cambiato per l'UISegmentControl a ordina i segmenti in ordine in base al loro valore x di origine, quindi effettua un ciclo e confronta la proprietà SelectedSegmentIndex. Ecco un esempio con ipotizzando un controllo segmentato di 4 segmenti:

@IBAction func indexChanged(sender: UISegmentedControl) { 

    let sortedViews = sender.subviews.sort({ $0.frame.origin.x < $1.frame.origin.x }) 

    for (index, view) in sortedViews.enumerate() { 
     if index == sender.selectedSegmentIndex { 
      view.tintColor = UIColor.blueColor() 
     } else { 
      view.tintColor = UIColor.lightGrayColor() 
     } 
    } 

} 

Poi viewDidLoad impostare la tintColor per il segmento inizialmente selezionato, in questo caso è il primo:

let sortedViews = segmentedControlOutletVariable.subviews.sort({ $0.frame.origin.x < $1.frame.origin.x }) 
sortedViews[0].tintColor = UIColor.blueColor() 
9

Il modo più semplice che ho trovato è:

segmentControl.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.redColor()], forState: UIControlState.Selected) 
+0

Funziona per casi semplici se si desidera modificare il colore del pulsante in base alla selezione. Avevo bisogno di cambiare un indice specifico a prescindere dallo stato selezionato per un'interfaccia utente personalizzata. –

-1
class MyUISegmentedControl: UISegmentedControl { 

    required init(coder aDecoder: NSCoder){ 
     super.init(coder: aDecoder)! 
     for subViewOfSegment: UIView in subviews { 
      subViewOfSegment.tintColor = UIColor.red 
     } 
    } 
} 
0

Questo codice funziona bene con l'ultima versione di Swift come il mar 2017 (Swift 3.0)

Questo codice che ho implementato è l'estensione per il controllo del segmento e può essere utilizzato per tutti i controlli di segmento nell'applicazione, in cui l'insieme di codice deve essere definito nella classe dell'applicazione.

Il metodo di estensione può essere utilizzato direttamente nell'applicazione, inoltre è possibile aggiungere tutte le impostazioni allo stesso metodo o metodi diversi nella classe di estensione, come mostrato di seguito.

extension UISegmentedControl { 
func setSegmentStyle() { 
    setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default) 
    setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default) 
    setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) 



    let segAttributes: NSDictionary = [ 
      NSForegroundColorAttributeName: UIColor.gray, 
      NSFontAttributeName: UIFont(name: "System-System", size: 14)! 
     ] 

     setTitleTextAttributes(segAttributes as [NSObject : AnyObject], for: UIControlState.selected) 
    } 

    // create a 1x1 image with this color 
    private func imageWithColor(color: UIColor) -> UIImage { 
     let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) 
     UIGraphicsBeginImageContext(rect.size) 
     let context = UIGraphicsGetCurrentContext() 
     context!.setFillColor(color.cgColor); 
     context!.fill(rect); 
     let image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
     return image! 
    } 
} 

Ovunque per i segmenti il ​​codice qui sotto può essere utilizzato

self.mySegment.setSegmentStyle() 

enter image description here

1

Dopo aver analizzato e cercando un sacco di risposte a questa e altre domande simili mi sono reso conto che con un 3rd-party controllo segmentato personalizzato sarà molto più facile e sicuro fare personalizzazioni rispetto al tentativo di hackerare UISegmentedControl di Apple.

Ecco un esempio di personalizzazione con XMSegmentedControl (Swift 3).

Alcuni in codice:

mySegmentControl.delegate = self 
    mySegmentControl.font = UIFont.systemFont(ofSize: 12) 

E alcuni in Interface Builder (può essere fatto in codice anche se volete):

enter image description here

Il risultato è:

enter image description here

Nel mio caso sembra molto simile al sistema uno, ma ci sono ancora piccole differenze che dovevo fare esattamente come il progettista voleva che fosse.

Si noti che XMSegmentedControl non consente di avere colori di sfondo diversi per segmenti diversi, ma è possibile aggiungerlo facilmente se necessario, poiché è un semplice file .swift, che è molto facile da capire e modificare.

+0

Ho aggiornato la mia risposta per mostrare le possibilità di personalizzazione. Il controllo segmentato personalizzato ha un codice semplice e chiaro: puoi facilmente modificarlo per poter impostare i singoli colori per ogni segmento. – Vitalii