有多行的UISegmentedControl文本?

如何使我的UISegmentedControl中的一个button的文本跨越多行?

我这样做了:

  • 创build一个多行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]; ... 

使用UIAppearance来完成任务。 下面的代码片段将工作。 在创build细分之前先调用它

Objective-C的

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

迅速

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

上面的方法更好,但为了有一个替代scheme,你可以做一些事情:

 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; } } } } 

Swift 4及以上的语法基于@Saranya Sivanandham的回答

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

多年后…

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