UISegmentedControl文本如何显示多行?

33

如何使 UISegmentedControl 中的一个按钮文本跨越多行?

7个回答

44

使用UIAppearance来完成任务。以下代码片段将起作用。在创建您的段之前调用此代码。

Objective-C

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

Swift

UILabel.appearanceWhenContainedInInstancesOfClasses([UISegmentedControl.self]).numberOfLines = 0

2
由于有人给我点了踩:它不应该工作(numberOfLines甚至不是UIAppearance选择器),但它实际上可以工作。证明:http://i.stack.imgur.com/gE7Dv.png 问题似乎是标签宽度仅从第一行中获取。这就是为什么我在代码中添加了这些空格的原因。 - Matthias Bauch
@MatthiasBauch 请尝试删除换行符。 - Saranya Sivanandham
没有换行符,它就不会成为多行标签。;) 无论如何,谢谢,但我不再有这个问题了,我已经一段时间以前用得票最高的答案解决了它。只是想解释一下,downvote是不必要的。 - Matthias Bauch
此 API 可在 iOS 9.0 及以上版本中使用。 - Yaroslav
这段代码适用于iOS 12:[[UILabel appearanceWhenContainedInInstancesOfClasses:@[[UISegmentedControl class]]] setNumberOfLines:0]; - R. Mohan
Swift 5(在AppDelegate中添加以使Storyboard中添加的控件起作用):UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0 - D. Pratt

32
我是这样做的:
  • 创建一个多行UILabel
  • 将标签填充N行文本
  • 将标签转换为UIImage
  • 将图像设置为段落内容

在iOS 4、5、6上运行得很顺畅。

iOS 5示例图片

在iOS 7上也可以运行(只需删除文本阴影)。

iOS 7示例图片

MultiLineSegmentedControl - 头文件

//
//  MultiLineSegmentedControl.h
//
//  Created by Jens Kreiensiek on 20.07.11.
//  Copyright 2011 SoButz. All rights reserved.
//
#import <Foundation/Foundation.h>

@interface MultiLineSegmentedControl : UISegmentedControl
- (void)setMultilineTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)segment;
@end

MultiLineSegmentedControl - 实现文件

//
//  MultiLineSegmentedControl.m
//
//  Created by Jens Kreiensiek on 20.07.11.
//  Copyright 2011 SoButz. All rights reserved.
//
#import "MultiLineSegmentedControl.h"
#import "UIView+LayerShot.h"

@interface MultiLineSegmentedControl()
@property (nonatomic, retain) UILabel *theLabel;
@end

@implementation MultiLineSegmentedControl
@synthesize theLabel;

- (void)dealloc
{
    self.theLabel = nil;
    [super dealloc];
}


- (UILabel *)theLabel
{
    if (!self->theLabel) {

        self->theLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        self->theLabel.textColor = [UIColor whiteColor];
        self->theLabel.backgroundColor = [UIColor clearColor];
        self->theLabel.font = [UIFont boldSystemFontOfSize:13];
        self->theLabel.textAlignment = UITextAlignmentCenter;
        self->theLabel.lineBreakMode = UILineBreakModeWordWrap;
        self->theLabel.shadowColor = [UIColor darkGrayColor];
        self->theLabel.numberOfLines = 0;
    }

    return self->theLabel;
}


- (void)setMultilineTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)segment
{
    self.theLabel.text = title;
    [self.theLabel sizeToFit];

    [self setImage:self.theLabel.imageFromLayer forSegmentAtIndex:segment];
}

@end

UIView+LayerShot - 头文件

//
//  UIView+LayerShot.h
//
//  Created by Jens Kreiensiek on 29.06.12.
//  Copyright (c) 2012 SoButz. All rights reserved.
//
#import <UIKit/UIKit.h>

@interface UIView (LayerShot)
- (UIImage *)imageFromLayer;
@end

UIView+LayerShot - 实现文件

//
//  UIView+LayerShot.m
//
//  Created by Jens Kreiensiek on 29.06.12.
//  Copyright (c) 2012 SoButz. All rights reserved.
//
#import "UIView+LayerShot.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (LayerShot)

- (UIImage *)imageFromLayer
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

@end

使用它就像普通的UISegmentedControl一样:

...

MultiLineSegmentedControl *segment = [[MultiLineSegmentedControl alloc] 
    initWithItems:[NSArray arrayWithObjects:@"A", @"B", nil]];

segment.segmentedControlStyle = UISegmentedControlStyleBar;
segment.frame = CGRectMake(0, 0, 200, segment.frame.size.height * 1.5);

[segment setMultilineTitle:@"Title A\nSubtitle A" forSegmentAtIndex:0];
[segment setMultilineTitle:@"Title B\nSubtitle B" forSegmentAtIndex:1];

[self.view addSubview:segment];
[segment release];

...

@SoButz:我看不到任何字幕。我创建了UISegmentedControl的子类,并添加了上面的代码。在我的视图控制器的viewDidLoad中创建了一个MultiLineSegmentedControl。但它没有显示字幕。我已经导入了“MultiLineSegmentedControl.h”。你能帮我吗?谢谢。 - iOSAppDev
iOSAppDev,我已经更新了示例到我现在在iOS 6上使用的方法。试一试吧... - Jenson
1
@SoButz:我的分段名称为@"All", @"My\nFriends",@"Closing\nSoon", @"Nearby"。但仍然没有正确显示。看一下这里出了什么问题? - iOSAppDev
我也遇到了与@iOSAppDev指定的相同问题。 - Harshit Gupta

16

基于Saranya Sivanandham的回答,Swift 3+语法。

UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0

3
对我来说不起作用 :( 有人尝试过这个并取得了预期的结果吗? - Niib Fouda
@Venkatesh Chejaria。是的,将这行代码添加到您的App Delegate或任何其他类中,都可以用于编程方式或从Storyboard添加的UISegmentedControl。 - Maverick

3
上面的方法更好些,但为了有备用方案,你可以这样做:
for(UIView *subview in segmentedControl.subviews) {
        if([NSStringFromClass(subview.class) isEqualToString:@"UISegment"]) {
            for(UIView *segmentSubview in subview.subviews) {
                if([NSStringFromClass(segmentSubview.class) isEqualToString:@"UISegmentLabel"]) {
                    UILabel *label = (id)segmentSubview;
                    label.numberOfLines = 2;
                    label.text = @"Hello\nWorld";
                    CGRect frame = label.frame;
                    frame.size = label.superview.frame.size;
                    label.frame = frame;
                }
            }
        }
    }

你好 @moby,感谢你的替代方案。 如果我想为我的标签文本提供不同的名称,我该如何在你的替代方案中实现? - benhi

1
多年以后...
     for segment in segmented.subviews{
        for label in segment.subviews{
            if let labels = label as? UILabel{
                labels.numberOfLines = 2

            }
        }
    }

不再工作 - Siempay

1
"

对于iOS 12,以下代码将完美运行

"
    [[UILabel appearanceWhenContainedInInstancesOfClasses:@[[UISegmentedControl class]]] setNumberOfLines:0];

0

我有一个带有UISegmentedControl的故事板,其中包含一些视图。我将这些控件拖到我的类中作为@IBOutlet。以下是一些代码,用于使分段控件中的标签多行:

class MyViewController: UIViewController {
  ...
  @IBOutlet weak var segmentedCtrl: UISegmentedControl!
  {
     didSet {
       // localize strings
       let text1 = ... // localizedString
       ...
       segmentedCtrl.setTitle(text1, forSegmentAt: 0)
       ...
       // Following code making multiple lines happen!
       UILabel.appearance(whenContainedInInstancesOf:     
         [UISegmentedControl.self]).numberOfLines = 0
     }
     ...
  } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接