【问题标题】:How to resize text (font) to fit in UISegment of UISegmentedControl?如何调整文本(字体)的大小以适应 UISegmentedControl 的 UISegment?
【发布时间】:2016-11-25 23:47:22
【问题描述】:

有没有什么办法可以减小 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;

但在这种情况下,每个段都有不同的大小。

我想保持每个段的大小相同,并希望减小可以适合UISegmentedControlUISegmentLabel (label) 的字体大小,例如minimumscalefactorminimumfontsizeadjustsFontSizeToFitWidth。当包含在UISegmentedControl 中时,这些属性不适用于标签。

如果有人可以帮助实现这一目标,将不胜感激!

提前致谢!!

【问题讨论】:

标签: ios objective-c uilabel uisegmentedcontrol


【解决方案1】:

试试这个,我希望这对你有帮助,你会知道它是如何工作的-

我有一个 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)

【讨论】:

  • 这是个好方法,但不适合我的情况,因为在我的情况下,段(标题)的数量不固定,有时它是动态的,有时是 2,有时可能是 5 或更多等等。但是你的方法非常好。为此 +1!
  • @Lion 谢谢..很高兴听到您的问题已经解决。
【解决方案2】:

我发现了问题,其实是我的错!!!我将numberOfLines,adjustsFontSizeToFitWidth,minimumScaleFactorTitleTextAttributes 设置在一起。如果我们设置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;

【讨论】:

    【解决方案3】:

    SWIFT 4

    标签中允许多行

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

    【讨论】:

      【解决方案4】:

      我在视图控制器中运行它,并在 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
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        现代 Swift 中最简单的解决方案是

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

        【讨论】:

          猜你喜欢
          • 2015-12-10
          • 2011-02-06
          • 2019-09-20
          • 1970-01-01
          • 1970-01-01
          • 2011-05-23
          • 1970-01-01
          • 2018-09-04
          相关资源
          最近更新 更多