72

で選択したセグメントの色をカスタマイズする方法はありますUISegmentedControlか?

segmentedController.tintColorセグメント化されたコントロール全体の色をカスタマイズできるプロパティを見つけました。問題は、プロパティに明るい色を選択するとtintColor、選択されたセグメントがほとんど認識できなくなることです(その色は、セグメント化されたコントロールの他の部分とほぼ同じであるため、選択されたセグメントと選択されていないセグメントを区別するのが困難です)。そのため、セグメント化された制御に適切な明るい色を使用することはできません。解決策は、選択したセグメントの色に対していくつかの個別のプロパティになりますが、見つかりません。誰かがこれを解決しましたか?

4

23 に答える 23

74

これは、選択したセグメントを任意のRGBカラーに変更するための最も簡単な方法です。サブクラス化やハッキングは必要ありません。

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

UIColor *newTintColor = [UIColor colorWithRed: 251/255.0 green:175/255.0 blue:93/255.0 alpha:1.0];
    segmentedControl.tintColor = newTintColor;

UIColor *newSelectedTintColor = [UIColor colorWithRed: 0/255.0 green:175/255.0 blue:0/255.0 alpha:1.0];
[[[segmentedControl subviews] objectAtIndex:0] setTintColor:newSelectedTintColor];

この例は、重要な手順を示しています。

  1. コントロールスタイルを「StyleBar」に設定します。これは、コントロールスタイルが機能するために必要です。
  2. コントロール全体の選択されていない色を最初にオレンジ色に設定します
  3. 選択したセグメントの色を緑に設定します

ノート:

  • 手順1と2は、Interface Builderで実行することも、図のようにコードで実行することもできます。ただし、ステップ3はコードでのみ実行できます
  • この「123.0/255.0」のような表記で設定されているカラー値は、UIColorで必要な正規化されたフロート値の代わりにRGB値を目立たせるための方法です(必要に応じて無視してください)
于 2011-05-09T04:30:50.807 に答える
53

UISegmentcontrolで選択したセグメントに色を追加する簡単な方法を見つけました

送信者はUISegmentControlです

for (int i=0; i<[sender.subviews count]; i++) 
{
    if ([[sender.subviews objectAtIndex:i]isSelected] ) 
    {               
    UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
    [[sender.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
   else 
    {
        [[sender.subviews objectAtIndex:i] setTintColor:nil];
    }
}

そのWorkingForMeをチェックしてください

于 2012-02-08T06:40:59.667 に答える
23

これを行うには、たとえば、セグメント化されたコントロールのサブビューを繰り返し処理してisSelectedプロパティをテストし、setTintColor:そのサブビューでメソッドを呼び出すなどして、選択したセグメントを見つける必要があります。

私はこれを、Interface BuilderのValueChangedイベントの各セグメント化されたコントロールにアクションを接続することによって行いました。これらを、本質的にmspragueの答えであるビューコントローラーファイルのこのメソッドに接続しました。

- (IBAction)segmentedControlValueChanged:(UISegmentedControl*)sender
{
    for (int i=0; i<[sender.subviews count]; i++)
    {
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[sender.subviews objectAtIndex:i]isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor whiteColor]];
        }
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[sender.subviews objectAtIndex:i] isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor blackColor]];
        }
    }
}

ユーザーがビューを開くたびにコントロールが正しく表示されるようにするには、メソッドをオーバーライドして-(void)viewDidAppear:animated、次のようにメソッドを呼び出す必要もあります。

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    //Ensure the segmented controls are properly highlighted
    [self segmentedControlValueChanged:segmentedControlOne];
    [self segmentedControlValueChanged:segmentedControlTwo];
}

一部のボーナスポイントでは、選択時に白の色合いを使用するようにセグメント化されたコントロールを設定したい場合は、選択時にテキストの色を黒に変更することもできます。次のように行うことができます。

//Create a dictionary to hold the new text attributes
NSMutableDictionary * textAttributes = [[NSMutableDictionary alloc] init];
//Add an entry to set the text to black
[textAttributes setObject:[UIColor blackColor] forKey:UITextAttributeTextColor];
//Set the attributes on the desired control but only for the selected state
[segmentedControlOne setTitleTextAttributes:textAttributes forState:UIControlStateSelected];

iOS 6の導入により、viewDidAppearメソッドで選択したアイテムの色合いの色を初めて設定しても機能しません。これを回避するために、グランドセントラルディスパッチを使用して、次のように1秒後に選択した色を変更しました。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self segmentedControlValueChanged:segmentedControlOne];
    });
于 2012-09-24T08:02:17.267 に答える
9

何らかの理由で、Appleは標準のUISegmentedControlsの色を変更することを許可していません。

ただし、セグメント化されたコントロールスタイルをUISegmentedControlStyleBarに変更するという「合法的な」方法があります。これにより、見た目が少し異なり、気に入らないかもしれませんが、色は使用できます。

    NSArray *itemArray = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];

//バーのスタイルと広告を変更して表示し、セグメント化されたコントローラーを解放します

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor colorWithRed:.9 green:.1 blue:.1 alpha:1]; 
[self.view addSubview:segmentedControl];
[segmentedControl release];

これがお役に立てば幸いです。

セブ・ケイド「私は助けに来ました」

于 2010-03-30T11:38:30.730 に答える
8

編集:このソリューションはiOS6では機能しません。以下のDavidThompsonの回答を参照してください。

このスレッドは本当に古いですが、簡単な答えはどれも私にとって適切に機能しませんでした。

選択解除されたセグメント化されたコントロールの色を元に戻す限り、受け入れられた回答は機能します。このようなものは、値が変更された関数で機能します。

for (int i=0; i<[control.subviews count]; i++) 
{
    if ([[control.subviews objectAtIndex:i]isSelected] ) 
    {               
        UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    } else {
        UIColor *tintcolor=[UIColor grayColor]; // default color
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
}
于 2012-05-25T17:29:20.300 に答える
7

これは古い質問ですが、xcode 11 +では、選択したセグメントの色合いを設定できます。ここに画像の説明を入力してください

コードでは、を使用できますselectedSegmentTintColor。利用可能なiOS13以降

于 2019-11-21T05:30:05.010 に答える
6

これが、uihackerのCustomSegmentedControlの修正バージョンです(コメントのクレジットを参照)。アイデアは、tintColorを変更する必要があるサブビューを見つける方法を、selectedIndexメソッドからisSelectedメソッドに変更することです。サブビューの順序がランダムに変化する3つ以上のセグメントを持つカスタムUISegmentedControlを使用していたためです(uihackerの「hasSetSelectedIndexOnce」フラグでもこれは修正されません!)。コードはまだ開発の初期段階にあるため、自己責任で使用してください。コメントは大歓迎です:)

また、Interface Builderにサポートを追加し、setSelectedSegmentIndexをオーバーライドして、色も更新するようにしました。楽しみ!

CustomSegmentedControl.h

//
//  CustomSegmentedControl.h
//
//  Created by Hlung on 11/22/54 BE.
//  Copyright (c) 2554 __MyCompanyName__. All rights reserved.
//
//  Credit: http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

@interface CustomSegmentedControl : UISegmentedControl {
    UIColor *offColor,*onColor;
}
@property (nonatomic,retain) UIColor *offColor,*onColor;
-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor;
@end

CustomSegmentedControl.m

#import "CustomSegmentedControl.h"

@interface CustomSegmentedControl (private)
-(void)setInitialMode;
-(void)toggleHighlightColors;
@end

@implementation CustomSegmentedControl

@synthesize offColor,onColor;

-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor {
    if (self = [super initWithItems:items]) {
        // Initialization code
        self.offColor = offcolor;
        self.onColor = oncolor;
        [self setInitialMode];

        // default to 0, other values cause arbitrary highlighting bug
        [self setSelectedSegmentIndex:0];
    }
    return self;
}
- (void)awakeFromNib {
    // default colors
    self.offColor = [UIColor colorWithWhite:0.8 alpha:1];
    self.onColor = self.tintColor;
    [self setInitialMode];

    [self setSelectedSegmentIndex:0];
}

-(void)setInitialMode
{
    // set essential properties
    [self setBackgroundColor:[UIColor clearColor]];
    [self setSegmentedControlStyle:UISegmentedControlStyleBar];

    // loop through children and set initial tint
    for( int i = 0; i < [self.subviews count]; i++ )
    {
        [[self.subviews objectAtIndex:i] setTintColor:nil];
        [[self.subviews objectAtIndex:i] setTintColor:offColor];
    }

    // listen for updates, [self setSelectedSegmentIndex:0] triggers UIControlEventValueChanged in 5.0, 4.3 doesn't (facepalm), use  if( self.window ) to fix this
    [self addTarget:self action:@selector(toggleHighlightColors) forControlEvents:UIControlEventValueChanged];
}

// ---------------
// hlung's version
// ---------------
-(void)toggleHighlightColors
{
    // the subviews array order randomly changes all the time, change to check for "isSelected" instead
    for (id v in self.subviews) {
        if ([v isSelected]) [v setTintColor:onColor];
        else [v setTintColor:offColor];
    }
}
// override: update color when set selection
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
    [super setSelectedSegmentIndex:selectedSegmentIndex];
    [self toggleHighlightColors];
}
// ---------------
@end
于 2011-11-22T09:50:33.193 に答える
3

これを使って:

[[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected];
于 2014-09-18T06:28:42.820 に答える
2

これがアプリストアによって承認されるかどうかはわかりませんが、UISegmentedControlにサブクラスを作成して、カスタムで選択された色と選択されていない色を設定できるようにしました。詳細については、メモを確認してください。

http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

于 2010-05-27T23:30:08.467 に答える
2

@jothikenpachiによって上記で提供された回答を明確にするために、次のUISegmentControllerカテゴリがiOS6で適切に機能し、セグメントで任意のオン/オフの配色を使用できることがわかりました。さらに、プライベートメソッドisSelected / setTintColor:が将来のOSリリースで変更された場合、正常に失敗します。プライベートAPI呼び出しなどに関する警告。

@implementation UISegmentedControl(CustomTintExtension) {
-(void) updateCustomTintColorOn:(UIColor*)onColor Off:(UIColor*)offColor {
// Convenience function to rest the tint colors after selection, called upon change of selected index

SEL tint = @selector(setTintColor:);

for (UIView *view in [self subviews]) {
    // Loop through the views...
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:nil];
    }
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:offColor];
    }
}

// Checking if segment subview is selected...
SEL isSelected = @selector(isSelected);
for (UIView *view in [self subviews]) {
    if ([view respondsToSelector:isSelected] && [view performSelector:isSelected withObject:nil])
    {
        [view performSelector:tint withObject:onColor];
        break;
    }
}

}

このカテゴリメソッドは、UISegmentControllerの- (IBAction) segmentAction: (id)senderメソッド内から呼び出されることに注意してください。

また、iOS6では、最初に管理UIViewControllerでこのメソッドを呼び出す必要があるように思われる- (void)viewDidAppear:(BOOL)animatedため、アニメーションがフラッシュする可能性があることにも注意してください。これを最小限に抑えるには、IBでUISegmentControllerのtintColorとして「offColor」を設定してみてください。

于 2012-10-02T03:59:27.283 に答える
2

iOS7でこの問題が発生しました。これはiOS6とは動作が異なります。

iOS 7では、選択したセグメントのラベルの色はUISegementControlの背景と同じ色です。iOS 7で変更する唯一の方法は、UISegmentControlの背景色を設定することです。

segmentControl.backgroundColor = customColor;
于 2014-01-06T21:52:32.870 に答える
2

これを使って、一気にすべての色を変えました。

mySegmentedControl.tintColor = [UIColor redColor]
于 2015-01-21T19:28:17.247 に答える
1

セグメントと同じインデックスを持つサブビューでタグを使用できることがわかりました。これにより、任意の順序でセグメントが正しく色付けされます。

// In viewWillAppear set up the segmented control 

// then for 3 segments:  
self.navigationItem.titleView = segmentedControl;
//Order of subviews can change randomly!, so Tag them with same index as segment
[[[segmentedControl subviews]objectAtIndex:0]setTag:0]; 
[[[segmentedControl subviews]objectAtIndex:1]setTag:1];
[[[segmentedControl subviews]objectAtIndex:2]setTag:2];


// color follows the selected segment
- (IBAction)mySelector:(id)sender {
selector = [sender selectedSegmentIndex]
  for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
  }
}

// in viewDidAppear for returning to the view
[segmentedControl setSelectedSegmentIndex:selector];
for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
}
于 2012-03-05T02:47:51.190 に答える
1

セグメントを切り替えるときに、上位2つのソリューションが機能しませんでした。

私の解決策は、View Controllerでセグメント変更イベントを処理し、セグメントが変更されるたびにこのメソッドを呼び出すことでした。

+ (void)setSegmentedControl:(UISegmentedControl *)segmentedControl 
              selectedColor:(UIColor *)selectedColor 
            deselectedColor:(UIColor *)deselectedColor
{
    for (int i = 0; i < segmentedControl.subviews.count; i++) 
    {
        id subView = [segmentedControl.subviews objectAtIndex:i];

        if ([subView isSelected])
            [subView setTintColor:selectedColor];
        else
            [subView setTintColor:deselectedColor];
    }    
}
于 2012-07-27T20:07:55.443 に答える
1

なぜ誰も言及していないのだろうかUIAppearanceProxy

Apple Doc ::

https://developer.apple.com/documentation/uikit/uisegmentedcontrol#1653545

サンプルコード:

    private class func applyUISegmentControlAppearance(){
    let apperance = UISegmentedControl.appearance()

    // Set Navigation bar Title colour
    let unselAttrib = [NSForegroundColorAttributeName:UIColor.yellow,
                                        NSFontAttributeName: UIFont.systemFont(ofSize: 15)]

    let selAttrib = [NSForegroundColorAttributeName:UIColor.red,
                     NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)]


    apperance.setTitleTextAttributes(unselAttrib, for: .normal)
    apperance.setTitleTextAttributes(selAttrib, for: .selected)
}

呼び出し元: このメソッドを呼び出し元から呼び出すことができAppDelegateます

application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool

于 2018-03-01T15:47:08.110 に答える
0

あなたのようなことをするために、文書化されていない機能やハックにアクセスしなければならないかもしれません。それは確かにアップルを激怒させ、それはあなたのアプリケーションの拒絶につながるかもしれません。

現在、解決策は、代わりに2つのボタンを使用し、クリックしたときに画像を交換するという他のトリックにあります。ボタンを近づけて、半分にセグメント化されたコントロールの画像を表示して、セグメント化されたコントロールのような錯覚を与えます。これが私が提案できるすべてです。

お役に立てれば。

ありがとう、

マッドハップ

于 2010-02-16T04:25:22.770 に答える
0

各セグメントにタグを付けてから、TintColorforTagを設定できます。

#define kTagOffState 0
#define kTagOnState  2

#define UIColorFromRGB(rgbValue) [UIColor \
        colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
        green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
        blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

//usage     UIColor color = UIColorFromRGB(0xF7F7F7);

 UIColor onColor = UIColorFromRGB(0xF7F7F7);
 UIColor offColor = UIColorFromRGB(0x878787);

        [multiStateControl setTag:kTagOffState forSegmentAtIndex:0];
        [multiStateControl setTag:kTagOnState forSegmentAtIndex:1];
        [multiStateControl setTintColor:onColor forTag:kTagOnState];
        [multiStateControl setTintColor:offColor forTag:kTagOffState];  
于 2012-02-28T18:09:45.637 に答える
0

上記の回答は非常に役に立ちました。セグメント化されたコントロールを使用して、ノブの精度を設定しています。私は上記の答えのハイブリッドを取り、これを思いついた:

-(void) viewDidLoad {

NSArray *segments = [NSArray arrayWithObjects:@"Course", @"Fine",nil];

[knob setPrecision:0.1]; // initial precision
// Set starting values

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segments];

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(120, 680, 228, 30);
[segmentedControl addTarget:self action:@selector(precisionSelect:) forControlEvents:UIControlEventValueChanged];
segmentedControl.momentary = YES;

[self.view addSubview:segmentedControl];
}   

- (void)precisionSelect:(UISegmentedControl*)sender
{   
    UIColor *tintcolor = [UIColor darkGrayColor];   
    if (sender.selectedSegmentIndex == 0) {
        [[sender.subviews objectAtIndex:0] setTintColor:nil];
        [[sender.subviews objectAtIndex:1] setTintColor:tintcolor];
    [knob setPrecision:0.1]; // Coarse
    } else {
        [[sender.subviews objectAtIndex:0] setTintColor:tintcolor];
        [[sender.subviews objectAtIndex:1] setTintColor:nil];
    [knob setPrecision:0.05]; // Fine
    }

}

これが他の人に役立つことを願っています。私にとっての鍵は、以下を使用して選択されていないインデックスをリセットできることでした。setTintColor:nil];

于 2012-08-11T11:47:50.810 に答える
0
- (IBAction)segmentControlValueChanged:(UISegmentedControl *)sender
{
    if ([[sender.subviews firstObject] respondsToSelector:@selector(setTintColor:)]) {
        for (id segment in sender.subviews) {
            if ([segment respondsToSelector:@selector(isSelected)] && [segment isSelected]) {
                [segment setTintColor:[UIColor redColor]];
            } else {
                [segment setTintColor:[UIColor grayColor]];
            }
        }
    }
}
于 2015-08-18T10:25:11.290 に答える
0
Try this solution.    

ここに画像の説明を入力してください

ここに画像の説明を入力してください

        @IBAction func dashBoardSegmentValueChanged(sender: AnyObject) {
            switch dashBoardSegment.selectedSegmentIndex
            {
            case 0:     
                sender.subviews.last?.backgroundColor = UIColor.whiteColor()
                sender.subviews.first?.backgroundColor =  UIColor.clearColor()

                break;
            case 1:            
                sender.subviews.first?.backgroundColor =  UIColor.whiteColor()
                sender.subviews.last?.backgroundColor = UIColor.clearColor()
                break;
            default:
                break;
            }
        }

Note: Make sure you select one segment subview as initial selected for easiness. It works if you have two segment subviews.
于 2016-01-06T05:40:48.240 に答える
0
- (IBAction)segmentedControlValueChanged:(UISegmentedControl *)sender {
    for (int i = 0; i < sender.subviews.count; i++) {
        UIControl *component = [sender.subviews objectAtIndex:i];
        if ([component respondsToSelector:@selector(isSelected)]) {
            UIColor *selectedColor = [UIColor greenColor];
            UIColor *normalColor   = [UIColor blackColor];
            UIColor *tint = component.isSelected ? selectedColor : normalColor;
            [component setTintColor:tint];
        }
    }
}
于 2016-08-24T07:47:47.600 に答える
0
[segmentedControl setSelectedSegmentTintColor:[UIColor darkGrayColor]];

//For iOS 13
于 2019-09-27T15:30:54.350 に答える
-1

このSwift4コードは私のために機能します

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)
于 2018-06-06T14:29:18.970 に答える