2012-05-03 4 views
16

Sto cercando di implementare un UISlider personalizzato (sottoclasse di UISlider), che si comporta in modo simile al cursore nativo che ha una luce attorno al pollice quando è evidenziato. Sto avendo problemi con questo, però.UISlider evidenzia lo stato con una larghezza del pollice diversa dal normale

La larghezza (effettiva) del pollice evidenziato è ovviamente maggiore del pollice normale (a causa del bagliore). Se aggiungo il pixel padding trasparente all'immagine di stato normale, in modo che entrambe le immagini abbiano la stessa larghezza, il problema è che il pollice di stato normale non sembra mai raggiungere la fine della traccia (raggiunge la fine, ma il padding rende sembra diversamente).

Se uso thumbRectForBounds: per bilanciare il pollice per allineare correttamente all'inizio della traccia, peggiora ulteriormente il problema all'altra estremità.

Se tengo entrambe le immagini larghe quanto devono essere (cioè, nessuna spaziatura sullo stato normale, e le due non hanno la stessa larghezza), mi sono avvicinato. Posso impostare l'offset in modo indipendente in thumbRectForBounds: basato su UIControl.state, ma sembra che ci sia un po 'di magia matematica dietro le quinte. L'unico posto in cui UISlider pensa che le immagini per entrambi gli stati si allineano perfettamente è il centro esatto.

Sembra che possa essere necessario implementare alcuni calcoli matematici che determinano l'offset dello stato di evidenziazione in base alla relativa posizione lungo la traccia. Avrebbe bisogno di un offset y di zero al centro (l'UISlider centrerebbe entrambe le immagini, il che significa che si allineano). Agli estremi, avrebbe bisogno di un offset a y che compensi completamente il bagliore. E in mezzo dovrebbe interpolare l'offset-y.

Questo sembra un sacco di lavoro per ricreare qualcosa che lo slider nativo fa però, quindi forse mi manca qualcosa di ovvio.

Aggiornamento soluzione attuale:

Non è del tutto portatile, dal momento che rende alcune ipotesi circa la dimensione del bagliore che viene aggiunto. Sto aggiungendo il bagliore con un'immagine anziché disegnarla direttamente sul CALayer. Non ho ancora testato quanto è performante.

In sostanza creo un livello che è un quadrato le cui dimensioni sono l'altezza dell'immagine del pollice di stato predefinita, la centra sopra il pollice e quindi disegna il bagliore (solo il bagliore, non un'immagine separata di un pollice con un bagliore , come si farebbe con un'immagine di stato hightlight) nel livello.

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value { 
    CGRect r = [super thumbRectForBounds:bounds trackRect:rect value:value]; 

    [thumbHighlightOverlayLayer removeFromSuperlayer]; 
    thumbHighlightOverlayLayer = [CALayer layer]; 

    int x = r.origin.x + (r.size.width/2) - (r.size.height/2); 
    thumbHighlightOverlayLayer.frame = CGRectMake(x, r.origin.y, r.size.height, r.size.height); 

    UIImage* thumbHighlightOverlayImage = [UIImage imageNamed:@"thumb-highlight"]; 
    thumbHighlightOverlayLayer.contents = (id)thumbHighlightOverlayImage.CGImage; 

    switch (self.state) { 
    case UIControlStateHighlighted: 
     [[self layer] addSublayer:thumbHighlightOverlayLayer]; 
     break; 
    default: 
     break; 
    } 

    return r; 
} 
+0

http://stackoverflow.com/questions/755510/customizing-uislider-look – VSN

+0

La domanda riguarda principalmente l'immagine della traccia, non l'immagine del pollice. Scrivere il mio slider potrebbe ancora essere l'unica risposta qui, ma poiché sto cercando di ricreare il comportamento nativo, mi chiedo ancora se c'è un modo per evitare di doverlo fare. – farski

risposta

1

invece di aggiungere l'effetto bagliore nell'immagine, potrebbe essere preferibile aggiungerlo dinamicamente. puoi usare CALayer per aggiungere l'effetto bagliore.

CALayer

+0

Interessante. Farò un tentativo, grazie. – farski

+0

Questo sarà piuttosto difficile, poiché UISlider non sembra avere alcuna sottoview o sottolivelli a cui si possa aggiungere un'ombra. –

+0

Come dice Andreas, questo non è completamente diretto in quanto non c'è un accesso diretto alla vista dell'immagine del pollice, ma ho trovato una soluzione che sembra funzionare. Grazie per l'idea, Tejesh. – farski

0

Si potrebbe rotolare il proprio dispositivo di scorrimento, che non è così complicato come può sembrare, ma richiederebbe comunque un paio d'ore di codifica.

Tuttavia, la soluzione più semplice sarebbe quella di appena impostato personalizzata immagini così:

  1. Crea personalizzato "minimo"/"massimo" le immagini della pista con imbottitura (pixel trasparenti) sul/lato destro e sinistro . L'imbottitura deve essere larga quanto il raggio della luminescenza meno il raggio del pollice (11pt).
  2. applicare immagini al vostro UISlider con setMinimumTrackImage:forState: e setMaximumTrackImage:forState:
  3. Aumenta il tuo larghezza di scorrimento per la dimensione dell'imbottitura aggiunto
0

mi sono imbattuto in un problema simile con un cursore personalizzato per una delle mie applicazioni. A differenza del normale slider, la traccia è una linea numerica statica, quindi non ho bisogno di immagini minime e massime separate. Eppure, avevo bisogno di un punto caldo extra per il pollice. Così ho fatto la mia immagine del pollice con imbottitura extra di pixel trasparenti, e ho assegnato immagini trasparenti alla traccia. La traccia visibile è solo una UIImageView dietro il cursore (in realtà una UIImageView dietro un gruppo di cursori). I bordi del cursore si estendono ben oltre i bordi dell'immagine della traccia.

Il mio suggerimento è quello di rendere la costruzione visiva del dispositivo di scorrimento desiderato combinando più viste invece di andare contro i limiti della personalizzazione di un UISlider. Se riesci a fare a meno di cambiare traccia, potresti duplicare la mia tecnica. Oppure puoi manipolare il frame di un UIView o due per regolare le tracce personalizzate ogni volta che il cursore cambia valore. Se è necessario utilizzare lo stesso dispositivo di scorrimento più di una volta nell'app, è possibile impacchettare il gruppo di viste in una sottoclasse UIView. A seconda di quanto sia complessa l'azione del cursore, potrebbe verificarsi un punto in cui la creazione di un controllo personalizzato sarebbe la scelta più prudente.

Problemi correlati