web-dev-qa-db-ja.com

複数行のUISegmentedControlテキスト?

UISegmentedControlのボタンの1つにあるテキストを複数行にまたがらせるにはどうすればよいですか?

30
Jason

UIAppearanceを使用して物事を成し遂げます。以下のコードスニペットが機能します。セグメントを作成する前にこれを呼び出します。

Objective-C

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

スイフト

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

私はそれをこのようにしました:

  • 複数行のUILabelを作成する
  • ラベルにN行のテキストを入力します
  • ラベルをUIImageに変換します
  • 画像をセグメントコンテンツとして設定する

これはiOS4、5、6でスムーズに機能します

Sample Image iOS 5

およびiOS7(テキストシャドウを削除するだけ)

Sample Image iOS 7

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-実装ファイル

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

IView + 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

IView + 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

通常の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];

...
31
Jenson

Swift 3 +構文は answer に基づいています@Saranya Sivanandham

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

上記のアプローチの方が優れていますが、代替手段を用意するために、次のようなことができます。

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

iOS 12の場合、以下のコードはチャームのように機能します

    [[UILabel appearanceWhenContainedInInstancesOfClasses:@[[UISegmentedControl class]]] setNumberOfLines:0];
0
R. Mohan

数年後...

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

            }
        }
    }
0
Emilio Hoffmann