2012-08-16 3 views
5

inizia così, che mi piace:
Screenshot1.pngCambia larghezza di un controllo segmentato in base ai titoli di ogni segmento?

ma poi ho aggiungere un segmento e questo accade:
Screenshot2.png La larghezza è impostata in IB, non nel codice.

Tutto ciò di cui ho bisogno è un metodo per calcolare la larghezza al volo. Alla fine, sarebbe fare qualcosa di simile:

control.width = (labelWidths + marginWidths); 
// where marginWidths = (marginWidth * control.numberOfSegments) 

risposta

7

Il metodo di risposta di prgrmr here funziona bene per lo scopo previsto, ma questo non è vero.

Invece di aggiungere un inutile sovraccarico con subviews UILabel personalizzato,
ho modificato il codice di esempio nel link qui sopra a venire con questo:

- (void)resizeSegmentsToFitTitles:(UISegmentedControl *)control { 
    CGFloat textWidth = 0; // total width of all text labels 
    CGFloat marginWidth = 0; // total width of all margins 
    NSUInteger nSegments = control.subviews.count; 
    UIView *aSegment = [control.subviews objectAtIndex:0]; 
    UIFont *theFont = nil; 

    // get font for segment title label 
    for (UILabel *label in aSegment.subviews) { 
     if ([label isKindOfClass:[UILabel class]]) { 
      theFont = label.font; 
      break; 
     } 
    } 

    // calculate width of text in each segment 
    for (NSUInteger i = 0; i < nSegments; i++) { 
     NSString *title = [control titleForSegmentAtIndex:i]; 
     CGFloat width = [title sizeWithFont:theFont].width; 
     CGFloat margin = 15; 

     if (width > 200) { 
      NSString *ellipsis = @"…"; 
      CGFloat width2 = [ellipsis sizeWithFont:theFont].width; 

      while (width > 200-width2) { 
       title = [title substringToIndex:title.length-1]; 
       width = [title sizeWithFont:theFont].width; 
      } 

      title = [title stringByAppendingString:ellipsis]; 
     } 

     [control setTitle:title forSegmentAtIndex:i]; 

     textWidth += width; 
     marginWidth += margin; 
    } 

    // resize segments to accomodate text size, evenly split total margin width 
    for (NSUInteger i = 0; i < nSegments; i++) { 
     // size for label width plus an equal share of the space 
     CGFloat textWidth = [[control titleForSegmentAtIndex:i] 
          sizeWithFont:theFont].width; 
     // the control leaves a 1 pixel gap between segments if width 
     // is not an integer value; roundf() fixes this 
     CGFloat segWidth = roundf(textWidth + (marginWidth/nSegments)); 
     [control setWidth:segWidth forSegmentAtIndex:i]; 
    } 

    // set control width 
    [control setFrame:CGRectMake(0, 0, (textWidth + marginWidth), 30)]; 
} 
+0

Sto usando questo in iOS7 per correggere un problema con il controller segmentato troncare i titoli quando non dovrebbe comunque l'ultimo segmento non è tapable ... alcuna ideea perché? – user1028028

+0

http://stackoverflow.com/questions/18890428/uisegmentedcontrol-truncates-segment-titles – user1028028

+0

[Qui] (http://stackoverflow.com/a/23492688/2254935) è semplificato e iOS 7 versione amichevole. –

18

È possibile utilizzare la proprietà apportionsSegmentWidthsByContent e impostarlo YES.

+0

Questo non sembra funzionare per me quando cambio il testo a livello di programmazione. – primehalo

+1

@primehalo Prova a impostare questa proprietà ogni volta che aggiorni il testo a livello di programmazione. – Rajesh

+0

Grazie a @Rajesh per la correzione rapida !! –

4

Come mostrato nella foto seguente, modificare la proprietà Auto-Size su "Proporzionale al contenuto".

enter image description here

+0

Questa dovrebbe essere la risposta accettata: è la più veloce, più semplice e funziona alla grande. Grazie, Ankit. –