Как изменить размер текста (шрифта), чтобы он поместился в UISegment of UISegmentedControl?

Есть ли способ уменьшить размер шрифта, который может поместиться в одном сегменте UISegmentedControl?

Перепробовал много чего-то вроде,

[[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] adjustsFontSizeToFitWidth];

[[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] setMinimumScaleFactor:0.5];

А ТАКЖЕ

 NSArray *arr = segment.subviews;  // segment is UISegmentedControl object

for (int i = 0; i < arr.count; i++) {

    UIView *aSegment = [arr objectAtIndex:i];

    for (UILabel *label in aSegment.subviews) {

        if ([label isKindOfClass:[UILabel class]]) {

            UILabel *myLabel = (UILabel *)label;

            [myLabel setNumberOfLines:0];

            label.numberOfLines = 0;
            label.adjustsFontSizeToFitWidth = YES;
            label.minimumScaleFactor = 0.5;
        }



    }
}

в состоянии установить количество строк метки сегмента, как,

  [[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] setNumberOfLines:0];

Можно установить размер одного сегмента, например,

  segment.apportionsSegmentWidthsByContent = YES;

но каждый сегмент имеет разный размер в этом случае.

Я хочу сохранить одинаковый размер каждого сегмента и уменьшить размер шрифта, который можно вписать в UISegmentLabel (label) из UISegmentedControl что-то вроде minimumscalefactor или же minimumfontsize или же adjustsFontSizeToFitWidth, Эти свойства не работают для метки, если они содержатся в UISegmentedControl,

Если кто-то может помочь достичь этого, это будет оценено!!

Заранее спасибо!!

5 ответов

Решение

Я нашел проблему, на самом деле это была моя ошибка!!! Я устанавливал numberOfLines,adjustsFontSizeToFitWidth,minimumScaleFactor а также TitleTextAttributes toghether. Если мы установим titleTextAttribute затем minimumScaleFactor не могу работать

Обновление: (как спросил @HawkEye1194 в комментарии к другому ответу)

Я в конечном итоге с решением ниже,

 //this will allow multiple lines in label contained by every segment in segmentedcontroller

[[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] setNumberOfLines:0];


UISegmentedControl *segment = [[UISegmentedControl alloc]initWithItems:option];
segment.frame = CGRectMake(20, 50, self.view.frame.size.width - 40, 50);
segment.tintColor = [UIColor grayColor];
segment.selectedSegmentIndex = 0;
segment.backgroundColor = [UIColor whiteColor];
segment.tag = segmentedControllerBaseTag;


[segment addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];

[segment setTitleTextAttributes:@{NSFontAttributeName :[UIFont fontWithName:@"HelveticaNeue" size:17.0], NSForegroundColorAttributeName : [UIColor darkGrayColor] } forState:UIControlStateNormal];
[segment setTitleTextAttributes:@{NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue" size:17.0],NSForegroundColorAttributeName : [UIColor whiteColor]} forState:UIControlStateSelected];

Если вы не устанавливаете текстовый атрибут заголовка, как указано выше, вы можете использовать приведенный ниже код

// ********** if titletextattributes are not set then below method works ***********

   for(uint i=0;i<[segment subviews].count;i++)
   {
    for(UIView *view in [[[segment subviews] objectAtIndex:i] subviews])
    {
        if([view isKindOfClass:[UILabel class]])
        {

            [(UILabel*)view setNumberOfLines:0];
            [(UILabel*)view setAdjustsFontSizeToFitWidth:YES];
            [(UILabel*)view setMinimumScaleFactor:0.7];


        }
    }
}

Вы можете настроить размер отдельного сегмента в соответствии с его содержимым с помощью кода ниже,

 //*************** adjust single segment size as per content

 segment.apportionsSegmentWidthsByContent = YES;

SWIFT 4

разрешить несколько строк в метке

if #available(iOS 9.0, *) {
    UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0
}

Попробуйте, надеюсь, это поможет вам, и вы поймете, как это работает.

у меня есть UISegmentedControl т.е. _userProfileSagmentOutlet имея три сегмента. Вот пример кода

CGFloat fontSize = 15;

[_userProfileSagmentOutlet setTitleTextAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-medium" size:fontSize],
                                                    NSForegroundColorAttributeName:[UIColor whiteColor]}
                                         forState:UIControlStateSelected];

[_userProfileSagmentOutlet setTitleTextAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-medium" size:fontSize],
                                                    NSForegroundColorAttributeName:[UIColor whiteColor]}
                                         forState:UIControlStateNormal];

это предыдущий код, который обрезает хвост заголовка, как показано ниже

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

Вот основная логика, которая соответствует каждому заголовку в сегментах с одинаковым размером шрифта

CGFloat fontSize = 15;

NSAttributedString* firstTitle = [[NSAttributedString alloc] initWithString:@"Membership History" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];

NSAttributedString* secondTitle = [[NSAttributedString alloc] initWithString:@"Event History" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];

NSAttributedString* thirdTitle = [[NSAttributedString alloc] initWithString:@"Booked Classes" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];


float maxW=MAX(MAX(firstTitle.size.width, secondTitle.size.width), thirdTitle.size.width);

while (maxW > _userProfileSagmentOutlet.subviews[0].frame.size.width) {

    fontSize--;

    firstTitle = [[NSAttributedString alloc] initWithString:@"Membership History" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];

    secondTitle = [[NSAttributedString alloc] initWithString:@"Event History" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];

    thirdTitle = [[NSAttributedString alloc] initWithString:@"Booked Classes" attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Roboto-medium" size:fontSize]}];

    maxW=MAX(MAX(firstTitle.size.width, secondTitle.size.width), thirdTitle.size.width);


}
[_userProfileSagmentOutlet setTitleTextAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-medium" size:fontSize],
                                                    NSForegroundColorAttributeName:[UIColor whiteColor]}
                                         forState:UIControlStateSelected];

[_userProfileSagmentOutlet setTitleTextAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-medium" size:fontSize],
                                                    NSForegroundColorAttributeName:[UIColor whiteColor]}
                                         forState:UIControlStateNormal];

после использования этого кода изображение выглядит следующим образом (тот же размер шрифта и размер текста подходят для сегмента и работает нормально)-

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

Вот расширение Swift, если кому-то нужно

    var fontSize:CGFloat = 15.0;

    var firstTitle = NSMutableAttributedString.init(string: "Membership History", attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)])

    var secondTitle = NSMutableAttributedString.init(string: "Events History" ,attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)]);

    var thirdTitle = NSMutableAttributedString.init(string: "Booked Classes" ,attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)]);

    var maxW:CGFloat = max(max(firstTitle.size().width, secondTitle.size().width), thirdTitle.size().width);

    while (maxW > userProfileSagmentOutlet.subviews[0].frame.size.width) {

        fontSize--;

         firstTitle = NSMutableAttributedString.init(string: "Membership History", attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)])

         secondTitle = NSMutableAttributedString.init(string: "Events History" ,attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)]);

         thirdTitle = NSMutableAttributedString.init(string: "Booked Classes" ,attributes:[NSFontAttributeName: UIFont.systemFontOfSize(fontSize)]);

         maxW = max(max(firstTitle.size().width, secondTitle.size().width), thirdTitle.size().width);

    }
    userProfileSagmentOutlet.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFontOfSize(fontSize),NSForegroundColorAttributeName:UIColor.whiteColor()], forState:UIControlState.Normal)

    userProfileSagmentOutlet.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFontOfSize(fontSize),NSForegroundColorAttributeName:UIColor.whiteColor()], forState:UIControlState.Selected)

Самым простым решением в современном Swift было бы

      override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
        
    _ = Your_UISegmentControl.subviews.compactMap { $0.subviews.compactMap {
        ($0 as? UILabel)?.adjustsFontSizeToFitWidth = true
        ($0 as? UILabel)?.minimumScaleFactor = 0.5
    }}
}

Я запустил это в контроллере представления и назвал его после viewDidAppear

      func autoshrinkSegmentFontSize() {
    for subview in segments.subviews {
        for label in subview.subviews {
            if let myLabel = subview as? UILabel {
                myLabel.adjustsFontSizeToFitWidth = true
                myLabel.minimumScaleFactor = 0.5
            }
        }
    }
}
Другие вопросы по тегам