UISegmentedControl text with multiple lines? UISegmentedControl text with multiple lines? xcode xcode

UISegmentedControl text with multiple lines?


Use UIAppearance to get things done. The below code snippet will work. Call this before creating your segment.

Objective-C

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

Swift

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


I did it this way:

  • create a multiline UILabel
  • fill the label with N lines of text
  • convert the label into an UIImage
  • set the image as a segments content

This works smooth on iOS 4, 5, 6

Sample Image iOS 5

and iOS 7 (just remove the text shadow)

Sample Image iOS 7

MultiLineSegmentedControl - header file

////  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 - implementation file

////  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 - header file

////  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 - implementation file

////  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

Use it just like a normal 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];...


Swift 3+ syntax based on answer by @Saranya Sivanandham

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