3

I have a segmented control in my iPhone app that works great on ios6 but on ios7 the segment tiles are truncated (there is enough space for the text, but it truncates them anyway)

    self.segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
self.segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
NSDictionary *defaultTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:defaultFont,
                                       UITextAttributeFont,
                                       defaultFontColor,
                                       UITextAttributeTextColor,
                                       nil];
[self.segmentedControl setTitleTextAttributes:defaultTextAttributes forState:UIControlStateNormal];

NSDictionary *selectedTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:selectedFont,
                                        UITextAttributeFont,
                                        selectedFontColor,
                                        UITextAttributeTextColor,
                                        nil];
[self.segmentedControl setTitleTextAttributes:selectedTextAttributes forState:UIControlStateHighlighted];

Any sugestions on how to fix this? Why would it work right on ios6 but truncate the titles on ios7...

This is the code that causes the problem...

      UIImage *unselectedBackgroundImage = [[UIImage imageNamed:@"product_details_segmentBckg"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];
    /* Selected background */
    UIImage *selectedBackgroundImage = [[UIImage imageNamed:@"product_details_segmentBckg"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];
    /* Image between two unselected segments */
    UIImage *bothUnselectedImage = [[UIImage imageNamed:@"product_details_segmentBckg"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 0, 1, 0)];
     /* Image between segment selected on the left and unselected on the right */
    UIImage *leftSelectedImage = [[UIImage imageNamed:@"product_details_segmentBckg"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 0, 1, 0)];
    /* Image between segment selected on the right and unselected on the right */
    UIImage *rightSelectedImage = [[UIImage imageNamed:@"product_details_segmentBckg"] resizableImageWithCapInsets:UIEdgeInsetsMake(1, 0, 1, 0)];

    if ([UIImage instancesRespondToSelector:@selector(imageWithRenderingMode:)]) {
#ifdef __IPHONE_7_0
        unselectedBackgroundImage = [unselectedBackgroundImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        selectedBackgroundImage = [selectedBackgroundImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        bothUnselectedImage = [bothUnselectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        leftSelectedImage = [leftSelectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        rightSelectedImage = [rightSelectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
#endif
    }


    [[UISegmentedControl appearance] setBackgroundImage:unselectedBackgroundImage
                                               forState:UIControlStateNormal
                                             barMetrics:UIBarMetricsDefault];

    [[UISegmentedControl appearance] setBackgroundImage:selectedBackgroundImage
                                               forState:UIControlStateSelected
                                             barMetrics:UIBarMetricsDefault];

    [[UISegmentedControl appearance] setDividerImage:bothUnselectedImage
                                 forLeftSegmentState:UIControlStateNormal
                                   rightSegmentState:UIControlStateNormal
                                          barMetrics:UIBarMetricsDefault];

    [[UISegmentedControl appearance] setDividerImage:leftSelectedImage
                                 forLeftSegmentState:UIControlStateSelected
                                   rightSegmentState:UIControlStateNormal
                                          barMetrics:UIBarMetricsDefault];

    [[UISegmentedControl appearance] setDividerImage:rightSelectedImage
                                 forLeftSegmentState:UIControlStateNormal
                                   rightSegmentState:UIControlStateSelected
                                          barMetrics:UIBarMetricsDefault];

If I comment this out the labels show up alright ... but I need the background images .... So how do I keep ios6 compatibility while also having the customized segmented control on ios7

user426132
  • 1,341
  • 4
  • 13
  • 28
  • Same thing, bro! Only that I'm not use any images for tabs - only titles. The most strange thing is that when app launched all titles looks good, but if you go to Home screen and back to app then when you tap on segmented control button then title of this button will truncated. It's iPad app. – alexey.metelkin Sep 20 '13 at 07:21
  • Well, I think I fixed it with setting of font for titles... So, it seems that you have different problem. Sorry – alexey.metelkin Sep 20 '13 at 09:29
  • http://stackoverflow.com/questions/11990330/change-width-of-a-segmented-control-based-on-titles-in-each-segment the accepted answer there is the solution to this problem. – user426132 Sep 20 '13 at 12:15

4 Answers4

2

I solved this by setting the same title text attributes that I had for the normal state, for the selected state. In iOS 6 this was enough:

NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   someUIFont, UITextAttributeFont,
                                   nil];

[self.segmentedControl setTitleTextAttributes:attributes forState:UIControlStateNormal];

Now I had to add this in order to make it work for iOS 7:

[self.segmentedControl setTitleTextAttributes:attributes forState:UIControlStateSelected];
  • This worked for me. And I find that _as long as the disabled state is the larger font size it won't truncate the label_. – darkheartfelt Feb 23 '16 at 02:41
1

after some research, here's my solution to the issue (Swift 3, iOS 10)

class CustomSegmentedControl: UISegmentedControl {

override func draw(_ rect: CGRect) {

    for segment in subviews {
        for subview in segment.subviews {
            if let segmentLabel = subview as? UILabel {
                segmentLabel.numberOfLines = 0
                segmentLabel.translatesAutoresizingMaskIntoConstraints = false
                segmentLabel.leadingAnchor.constraint(equalTo: segment.leadingAnchor).isActive = true
                segmentLabel.trailingAnchor.constraint(equalTo: segment.trailingAnchor).isActive = true
                segmentLabel.topAnchor.constraint(equalTo: segment.topAnchor).isActive = true
                segmentLabel.bottomAnchor.constraint(equalTo: segment.bottomAnchor).isActive = true
            }
        }
    }
}

override func didMoveToSuperview() {
    self.layer.cornerRadius = 5
    self.clipsToBounds = true
    self.backgroundColor = .white
    self.tintColor = UIColor.orange

    let font = UIFont(name: "Helvetica", size: 12.0)
    self.setTitleTextAttributes([NSFontAttributeName: font!], for: .normal)

    let fontBold = UIFont(name: "Helvetica-Bold", size: 12.0)
    self.setTitleTextAttributes([NSFontAttributeName: fontBold!], for: .selected)
}
}
Arnaud
  • 955
  • 1
  • 6
  • 15
0

I tried some solutions to avoid to recalculate all the segment sizes.
To fix my issue I put this code on the valueChange action of the segmented control:

for(int i=0;i<setControl.subviews.count; i++){
  NSString *title=[segControl titleForSegmentAtIndex:i];
  [segControl setTitle:title forSegmentAtIndex:i];
}

The problem happens with an App compiled for iOS6 (with Xcode 4.6.3) that runs on iOS7. The glitch is visible after the App is reactivated from suspension but not in all Views.

Punkman
  • 554
  • 6
  • 15
0

I was updating the title and it was getting truncated since the original title's length was less than the new title. So, I added permanent non-breaking space \u{00a0} in the text of original title so match the length of the title before and after.

Ali
  • 2,427
  • 22
  • 25