Изменение ширины сегментированного элемента управления на основе заголовков в каждом сегменте?


Начинается так, что мне нравится:
Screenshot1.формат PNG

Но затем я добавляю сегмент, и это происходит:
Скриншот 2.формат PNG Ширина задается в IB, а не в коде.

Все, что мне нужно, - это метод расчета ширины на лету. В конце концов, он сделал бы что-то вроде этого:

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

4 ответа:

Можно использовать свойствоapportionsSegmentWidthsByContent и установить его вYES.

Метод в ответе prgrmrздесь прекрасно работает по своему прямому назначению, но это не так.

Вместо добавления ненужных накладных расходов с пользовательскими подвидами UILabel,
Я изменил пример кода в приведенной выше ссылке, чтобы придумать это:

- (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)];
}

Как показано на рисунке ниже, измените свойство Auto-Size на "пропорционально содержанию".

Введите описание изображения здесь

Первый вариант выглядит так:

segmentedControl.setWidth(100, forSegmentAt: 0)
segmentedControl.setWidth(50, forSegmentAt: 1)

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

segmentedControl.apportionsSegmentWidthsByContent = true

Это передает полный контроль над iOS, что, вероятно, лучше всего делать большую часть времени.

Доступно с iOS 5.0

Hackingwithswift