问题
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
回答1:
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];
回答2:
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)
}
}
回答3:
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.
来源:https://stackoverflow.com/questions/18890428/uisegmentedcontrol-truncates-segment-titles