234

Can anyone please tell me how can I change the font type and size of UISegmentedControl?

TheNeil
  • 3,321
  • 2
  • 27
  • 52
Aashutosh Tiwari
  • 2,361
  • 2
  • 15
  • 5
  • 1
    Any solutions in IB instead of code? – oky_sabeni Mar 26 '15 at 00:06
  • you can not do it in IB. the current **2021** syntax is: UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.font: _font], for: .normal) – Fattie Oct 11 '21 at 13:07

17 Answers17

528

I ran into the same issue. This code sets the font size for the entire segmented control. Something similar might work for setting the font type. Note that this is only available for iOS5+

Obj C:

UIFont *font = [UIFont boldSystemFontOfSize:12.0f];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font
                                                       forKey:NSFontAttributeName];
[segmentedControl setTitleTextAttributes:attributes 
                                forState:UIControlStateNormal];

EDIT: UITextAttributeFont has been deprecated - use NSFontAttributeName instead.

EDIT #2: For Swift 4 NSFontAttributeName has been changed to NSAttributedStringKey.font.

Swift 5:

let font = UIFont.systemFont(ofSize: 16)
segmentedControl.setTitleTextAttributes([NSAttributedString.Key.font: font], for: .normal)

Swift 4:

let font = UIFont.systemFont(ofSize: 16)
segmentedControl.setTitleTextAttributes([NSAttributedStringKey.font: font],
                                        for: .normal)

Swift 3:

let font = UIFont.systemFont(ofSize: 16)
segmentedControl.setTitleTextAttributes([NSFontAttributeName: font],
                                        for: .normal)

Swift 2.2:

let font = UIFont.systemFontOfSize(16)
segmentedControl.setTitleTextAttributes([NSFontAttributeName: font], 
    forState: UIControlState.Normal)

Thanks to the Swift implementations from @audrey-gordeev

Ryan Stone
  • 27
  • 1
  • 9
johngraham
  • 6,461
  • 2
  • 16
  • 22
  • 4
    This works great, though if I have already done a `[mySegmentedControl setTintColor:onColor forTag:kTagOnState];` and a `[mySegmentedControl setTintColor:offColor forTag:kTagOffState];` then apply the `[mySegmentedControl setTitleTextAttributes:attributes forState:UIControlStateNormal];` then the Colors I just set go away. – scooter133 Feb 28 '12 at 18:04
  • You need to use dictionaryWithObjects:forKeys instead and create two arrays with your object and key attributes. – runmad Apr 15 '12 at 00:02
  • 3
    available in iOS 5.0 or later – rakeshNS Sep 13 '12 at 09:31
  • 8
    in iOS7: `NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldsystemFontOfSize:12.0f]};` – Jason Moore Oct 29 '13 at 20:25
  • 2
    @JasonMoore `boldSystemFontOfSize:` (capital S for System) – Guillaume Feb 28 '14 at 14:01
  • 1
    Works a treat in iOS 8. Remind me again, WHY is there no "font" attribute...? (Apple has a lot of explaining to do...!) – Mike Gledhill Feb 05 '15 at 13:16
  • You can drop the key down to simply `.font` as well – Patrick Perini Apr 12 '19 at 22:44
  • You actually have to call it like this let font = UIFont.systemFont(ofSize: 16) UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.font: font], for: .normal) – Coding while Loading Jul 14 '19 at 19:51
  • this answer is wrong in 2021 – Fattie Oct 11 '21 at 13:07
52

Use the Appearance API in iOS 5.0+:

[[UISegmentedControl appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"STHeitiSC-Medium" size:13.0], UITextAttributeFont, nil] forState:UIControlStateNormal];

Links: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIAppearance_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40010906

http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5

Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
38

Here is a Swift version of the accepted answer:

Swift 3:

let font = UIFont.systemFont(ofSize: 16)
segmentedControl.setTitleTextAttributes([NSFontAttributeName: font],
                                        for: .normal)

Swift 2.2:

let font = UIFont.systemFontOfSize(16)
segmentedControl.setTitleTextAttributes([NSFontAttributeName: font], 
    forState: UIControlState.Normal)
Andrey Gordeev
  • 30,606
  • 13
  • 135
  • 162
13

Another option is to apply a transform to the control. However, it will scale down everything including the control borders.

segmentedControl.transform = CGAffineTransformMakeScale(.6f, .6f);
Daniel
  • 201
  • 4
  • 5
9

Swift Style:

UISegmentedControl.appearance().setTitleTextAttributes(NSDictionary(objects: [UIFont.systemFontOfSize(14.0)], forKeys: [NSFontAttributeName]), forState: UIControlState.Normal)
Peter Kreinz
  • 7,979
  • 1
  • 64
  • 49
8

Here i have updated for iOS8

[[UISegmentedControl appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"STHeitiSC-Medium" size:13.0], NSFontAttributeName, nil] forState:UIControlStateNormal];
karthikeyan
  • 3,821
  • 3
  • 22
  • 45
7

XCode 8.1, Swift 3

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UISegmentedControl.appearance().setTitleTextAttributes(NSDictionary(objects: [UIFont.systemFont(ofSize: 24.0)], 
        forKeys: [NSFontAttributeName as NSCopying]) as? [AnyHashable : Any], 
        for: UIControlState.normal)
    }
}

just change the number value (ofSize: 24.0)

Preview

byJeevan
  • 3,728
  • 3
  • 37
  • 60
HÄsh HÄsh
  • 89
  • 1
  • 7
4
// Set font-size and font-femily the way you want
UIFont *objFont = [UIFont fontWithName:@"DroidSans" size:18.0f];

// Add font object to Dictionary
NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];

// Set dictionary to the titleTextAttributes
[yourSegment setTitleTextAttributes:dictAttributes forState:UIControlStateNormal];

If you have any query, Contact me.

Politta
  • 400
  • 4
  • 10
4

In swift 5,

let font = UIFont.systemFont(ofSize: 16)
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.font: font], for: .normal)
np2314
  • 645
  • 5
  • 14
3

C# / Xamarin:

segment.SetTitleTextAttributes(new UITextAttributes { 
    Font = UIFont.SystemFontOfSize(font_size) }, UIControlState.Normal);
t9mike
  • 1,546
  • 2
  • 19
  • 31
3

Correct answer for 2021. The syntax changed.

The 12 year old answer (even the edits to it) is broken.

It's just:

let _font = UIFont.systemFont(ofSize: 10)
UISegmentedControl.appearance()
 .setTitleTextAttributes([NSAttributedString.Key.font: _font], for: .normal)

It's very likely you will want to change the height correctly while you are at it:

import UIKit

class SmallerSegmentedControl: UISegmentedControl {

    override init(frame: CGRect) {
        super.init(frame: frame)
        common()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        common()
    }

    func common() {
        let _font = UIFont.systemFont(ofSize: 10)
        UISegmentedControl.appearance()
         .setTitleTextAttributes([NSAttributedString.Key.font: _font], for: .normal)
    }

    override var intrinsicContentSize:CGSize {
        var s = super.intrinsicContentSize
        s.height = 24
        return s
    }

}
Fattie
  • 27,874
  • 70
  • 431
  • 719
2
 UISegmentedControl.appearance().setTitleTextAttributes(NSDictionary(objects: [UIFont.systemFont(ofSize: 16.0)],
                                                                        forKeys: [kCTFontAttributeName as! NSCopying]) as? [AnyHashable : Any],
                                                           for: UIControlState.normal)
Davender Verma
  • 503
  • 2
  • 12
  • While this code may answer the question, providing information on how and why it solves the problem improves its long-term value – L_J Aug 23 '18 at 06:29
2

Swift 4

let font = UIFont.systemFont(ofSize: 16)
UISegmentedControl.setTitleTextAttributes([NSFontAttributeName: font], for: .normal)
drew..
  • 3,234
  • 3
  • 16
  • 19
  • Error : `Instance member 'setTitleTextAttributes' cannot be used on type 'UISegmentedControl'; did you mean to use a value of this type instead?` **iOS13/Swift5** – Sky Dec 31 '19 at 08:54
2

Daniel pointed me to correct way. I used it like this-

float scaleFactor = 0.8f;

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]
initWithFrame:CGRectMake(10, 70, 300/scaleFactor,35)];

[segmentedControl insertSegmentWithTitle:@"..." atIndex:0 animated:NO];
[segmentedControl insertSegmentWithTitle:@"..." atIndex:1 animated:NO];
[segmentedControl insertSegmentWithTitle:@"..." atIndex:2 animated:NO];

segmentedControl.transform = CGAffineTransformMakeScale(scaleFactor, 1);
CGPoint segmentedControlCenter = segmentedControl.center;
segmentedControlCenter.x = self.center.x;
segmentedControl.center = segmentedControlCenter;
Ved
  • 612
  • 6
  • 10
1

Extension for UISegmentedControl for setting Font Size.

extension UISegmentedControl {
    @available(iOS 8.2, *)
    func setFontSize(fontSize: CGFloat) {
            let normalTextAttributes: [NSObject : AnyObject]!
            if #available(iOS 9.0, *) {
                normalTextAttributes = [
                    NSFontAttributeName: UIFont.monospacedDigitSystemFontOfSize(fontSize, weight: UIFontWeightRegular)
                ]
            } else {
                normalTextAttributes = [
                    NSFontAttributeName: UIFont.systemFontOfSize(fontSize, weight: UIFontWeightRegular)
                ]
            }

        self.setTitleTextAttributes(normalTextAttributes, forState: .Normal)
    }
 }
byJeevan
  • 3,728
  • 3
  • 37
  • 60
GameBegins
  • 580
  • 7
  • 12
0

this is for objective c add your segmented control name in place of mysegmentedcontrol

UIFont *font = [UIFont systemFontOfSize:11.0f];

NSDictionary *attributes = [NSDictionary dictionaryWithObject:font
                                                            forKey:UITextAttributeFont];

[mySegmentedcontrol setTitleTextAttributes:attributes                                    forState:UIControlStateNormal];

hope it helps

Uma Madhavi
  • 4,851
  • 5
  • 38
  • 73
  • 1
    -- update -- NSDictionary *attributes = @{NSFontAttributeName:font}; [mySegmentedcontrol setTitleTextAttributes:attributes forState:UIControlStateNormal]; – Benny Davidovitz Oct 23 '18 at 19:45
0

You can get at the actual font for the UILabel by recursively examining each of the views starting with the UISegmentedControl. I don't know if this is the best way to do it, but it works.

@interface tmpSegmentedControlTextViewController : UIViewController {
}

@property (nonatomic, assign) IBOutlet UISegmentedControl * theControl;

@end

@implementation tmpSegmentedControlTextViewController

@synthesize theControl; // UISegmentedControl

- (void)viewDidLoad {
  [self printControl:[self theControl]];
  [super viewDidLoad];
}

- (void) printControl:(UIView *) view {
  NSArray * views = [view subviews];
  NSInteger idx,idxMax;
  for (idx = 0, idxMax = views.count; idx < idxMax; idx++) {
    UIView * thisView = [views objectAtIndex:idx];
    UILabel * tmpLabel = (UILabel *) thisView;
    if ([tmpLabel respondsToSelector:@selector(text)]) {
      NSLog(@"TEXT for view %d: %@",idx,tmpLabel.text);
      [tmpLabel setTextColor:[UIColor blackColor]];
    }

    if (thisView.subviews.count) {
      NSLog(@"View has subviews");
      [self printControl:thisView];
    }
  }
}

@end

In the code above I am just setting the text color of the UILabel, but you could grab or set the font property as well I suppose.

Primc
  • 368
  • 4
  • 10
  • This is a great way to make sure than an iOS update will break code that you've shipped to your customers. This might work now, but there's absolutely no guarantees that this will continue working in the future. – Apoorv Khatreja Oct 15 '18 at 16:10