【问题标题】:UISegmentedControl text with multiple lines?UISegmentedControl 多行文本?
【发布时间】:2011-08-02 15:00:56
【问题描述】:

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

【问题讨论】:

  • 关于您的问题的任何更新?

标签: iphone xcode ios interface-builder uisegmentedcontrol


【解决方案1】:

我是这样做的:

  • 创建多行 UILabel
  • 用 N 行文本填充标签
  • 将标签转换为 UIImage
  • 将图片设置为分段内容

这在 iOS 4、5、6 上运行流畅

和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。但它没有显示字幕。我有#import“MultiLineSegmentedControl.h”。你能帮助我吗 ?谢谢
  • iOSAppDev,我已将示例更新为我现在在 iOS 6 上使用的方法。试一试...
  • @SoButz:我的段名称为@"All"、@"My\nFriends"、@"Closing\nSoon"、@"Nearby"。但它仍然没有正确显示。 Have a look这里出了什么问题?
  • m 也遇到@iOSAppDev 指定的同样问题
【解决方案2】:

上面的方法更好,但为了有替代方案,您可以执行以下操作:

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,感谢您的选择。如果我想为我的标签文本指定一个不同的名称,我该怎么做?
【解决方案3】:

使用 UIAppearance 完成任务。下面的代码 sn-p 将起作用。在创建细分之前调用它。

Objective-C

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

斯威夫特

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

【讨论】:

  • 因为有人反对:它不应该工作(numberOfLines 甚至不是 UIAppearance 选择器),但它确实有效。证明:i.stack.imgur.com/gE7Dv.png 问题似乎是标签宽度似乎只取自第一行。这就是我在代码中添加这些空格的原因。
  • @MatthiasBauch 尝试删除换行符
  • 没有换行符就不是多行标签。 ;) 无论如何,谢谢,但我不再有这个问题了,我不久前用最高投票的答案解决了这个问题。只是想解释一下没有必要投反对票。
  • 此 API 适用于 iOS 9.0+。
  • [[UILabel appearanceWhenContainedInInstancesOfClasses:@[[UISegmentedControl class]]] setNumberOfLines:0];此代码适用于 iOS 12
【解决方案4】:

Swift 3+ 语法基于@Saranya Sivanandham 的answer

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

【讨论】:

  • 它对我不起作用 :( 有没有人尝试过这个并且得到了预期的结果??
  • @Venkatesh Chejaria。是的,在您的 App Delegate 或任何其他类中添加这一行将适用于以编程方式或从 Storyboard 添加的 UISegmentedControl。
【解决方案5】:

几年后...

     for segment in segmented.subviews{
        for label in segment.subviews{
            if let labels = label as? UILabel{
                labels.numberOfLines = 2

            }
        }
    }

【讨论】:

    【解决方案6】:

    对于 iOS 12,下面的代码将像魅力一样工作

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

    【讨论】:

      猜你喜欢
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2012-10-17
      相关资源
      最近更新 更多