Как я могу рассчитать правильную ширину для сегментов UISegmentedControl? - PullRequest
10 голосов
/ 14 июля 2011

Я пытаюсь использовать UISegmentedControl, но у меня проблемы с вычислением ширины сегментов. Элемент управления делает сегменты одинаковой ширины, что не работает для некоторых заголовков, таких как этот:

http://morrisphotoart.com/tmp/Screenshot2011-07-13_21.17.33.png

Я могу написать код для вычисления ширины сегмента, если я знал, какой шрифт, и вызвать метод setWidth: forSegmentAtIndex:, но как мне получить шрифт? Или есть другой способ?

Заголовки левого и среднего сегментов не фиксированы, поэтому я не могу жестко кодировать ширину.

Ответы [ 4 ]

28 голосов
/ 06 марта 2013

Если вы можете поддерживать iOS 5 и более поздние версии, вы можете использовать свойство apportionsSegmentWidthsByContent и установить его на YES.

Из документов iOS 5 :

apportionsSegmentWidthsByContent

Указывает, пытается ли элемент управления настроить ширину сегментов на основе их ширины содержимого.

@ свойство (неатомное) BOOL apportionsSegmentWidthsByContent

Обсуждение

Если значение этого свойства равно YES, для сегментов, значение ширины которых равно 0, элемент управления пытается настроить ширину сегментов на основе ширины их содержимого.

26 голосов
/ 16 июля 2011

РЕДАКТИРОВАТЬ: более простым вариантом может быть использование свойства iOS 5 apportionsSegmentWidthsByContent, как упомянуто в ответе @ Camsoft's здесь


Ну, яв конечном итоге получил UIFont от прослушивания подпредставлений (которые могут сломаться в будущем iOS).Будучи поклонником модульного / повторного использования, я написал эту процедуру, чтобы сделать это, а затем распределить пространство таким образом, чтобы сегменты в элементе управления были равномерно распределены по заголовкам.

-(void)resizeSegmentsToFitTitles:(UISegmentedControl*)segCtrl {
    CGFloat totalWidths = 0;    // total of all label text widths
    NSUInteger nSegments = segCtrl.subviews.count;    
    UIView* aSegment = [segCtrl.subviews objectAtIndex:0];
    UIFont* theFont = nil;

    for (UILabel* aLabel in aSegment.subviews) {
        if ([aLabel isKindOfClass:[UILabel class]]) {
            theFont = aLabel.font;
            break;
        }
    }

    // calculate width that all the title text takes up
    for (NSUInteger i=0; i < nSegments; i++) {
        CGFloat textWidth = [[segCtrl titleForSegmentAtIndex:i] sizeWithFont:theFont].width;
        totalWidths += textWidth;
    }

    // width not used up by text, its the space between labels
    CGFloat spaceWidth = segCtrl.bounds.size.width - totalWidths;   

    // now resize the segments to accomodate text size plus 
    // give them each an equal part of the leftover space
    for (NSUInteger i=0; i < nSegments; i++) {
        // size for label width plus an equal share of the space
        CGFloat textWidth = [[segCtrl titleForSegmentAtIndex:i] sizeWithFont:theFont].width;
        // roundf??  the control leaves 1 pixel gap between segments if width 
        // is not an integer value, the roundf fixes this
        CGFloat segWidth = roundf(textWidth + (spaceWidth / nSegments));    
        [segCtrl setWidth:segWidth forSegmentAtIndex:i];
    }
}
8 голосов
/ 14 июля 2011
NSArray *itemArray = [NSArray arrayWithObjects: @"Title1", @"Title2", @"Titl3", @"Title4",nil];
segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.frame = CGRectMake(0, 0, 310, 35);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.selectedSegmentIndex = 0;
[segmentedControl addTarget:self action:@selector(pickOne:) forControlEvents:UIControlEventValueChanged];   
segmentedControl.tintColor=[UIColor grayColor];

for (id segment in [segmentedControl subviews]) 
{
    for (id label in [segment subviews]) 
    {
        if ([label isKindOfClass:[UILabel class]])
        {

            [label setTextAlignment:UITextAlignmentCenter];
            [label setFont:[UIFont boldSystemFontOfSize:12]];
        }
    }           
}
0 голосов
/ 06 мая 2014

iOS 7.1.1. Мы рассчитали UISegmentedControl только для нового размера кадра, а остальное (пропорции сегментов) будет адресовано iOS (на основе apportionsSegmentWidthsByContent).

Имейте в виду, что это не работает, если включена автоматическая разметка.

void styleSegment_fitTitles(UISegmentedControl *segCtrl) {

    // Fit segments' titles
    [segCtrl sizeToFit];

    CGFloat em = font.pointSize;
    CGRect segCtrlRect = segCtrl.bounds;
    CGFloat segCtrlWidth = segCtrlRect.size.width + segCtrl.numberOfSegments*em;
    CGFloat segCtrlHeight = segCtrlRect.size.height + em;
    CGFloat segmentY = segCtrl.frame.origin.y - (segCtrlHeight - segCtrlRect.size.height)/2;
    segCtrl.frame = CGRectMake(segCtrl.frame.origin.x, segmentY, segCtrlWidth, segCtrlHeight);
}
...