简体   繁体   English

UISegmentedControl 多行文本?

[英]UISegmentedControl text with multiple lines?

如何使 UISegmentedControl 中的一个按钮中的文本跨越多行?

Use UIAppearance to get things done.使用 UIAppearance 完成任务。 The below code snippet will work.下面的代码片段将起作用。 Call this before creating your segment.在创建细分之前调用它。

Objective-C 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创建多行 UILabel
  • fill the label with N lines of text用 N 行文本填充标签
  • convert the label into an UIImage将标签转换为 UIImage
  • set the image as a segments content将图像设置为分段内容

This works smooth on iOS 4, 5, 6这在 iOS 4、5、6 上运行流畅

示例图像 iOS 5

and iOS 7 (just remove the text shadow)和 iOS 7(只需删除文本阴影)

示例图像 iOS 7

MultiLineSegmentedControl - header file 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 - implementation file 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 - header file 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 - implementation file 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

Use it just like a normal UISegmentedControl:像普通的 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];

...

基于@Saranya Sivanandham回答Swift 3+语法

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

The approach above is better, but for the sake of having an alternative, you can do something like:上面的方法更好,但为了有替代方案,您可以执行以下操作:

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

Years later...多年后...

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

            }
        }
    }

对于iOS 12 ,下面的代码将像魅力一样工作

    [[UILabel appearanceWhenContainedInInstancesOfClasses:@[[UISegmentedControl class]]] setNumberOfLines:0];

I have a storyboard with UISegmentedControl in some views.在某些视图中,我有一个带有 UISegmentedControl 的故事板。 I drag those controls to my class as @IBOutlet .我将这些控件作为@IBOutlet拖到我的班级。 Here are some codes to make labels in segmented controls multiple lines:以下是一些在分段控件中制作多行标签的代码:

class MyViewController: UIViewController {
  ...
  @IBOutlet weak var segmentedCtrl: UISegmentedControl!
  {
     didSet {
       // localize strings
       let text1 = ... // localizedString
       ...
       segmentedCtrl.setTitle(text1, forSegmentAt: 0)
       ...
       // Following code making multiple lines happen!
       UILabel.appearance(whenContainedInInstancesOf:     
         [UISegmentedControl.self]).numberOfLines = 0
     }
     ...
  } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM