UFO ET IT

UISegmentedControl 선택한 세그먼트 색상

ufoet 2020. 11. 9. 21:41
반응형

UISegmentedControl 선택한 세그먼트 색상


에서 선택한 세그먼트의 색상을 사용자 정의하는 방법이 UISegmentedControl있습니까?

segmentedController.tintColor전체 세그먼트 컨트롤의 색상을 사용자 지정할 수있는 속성을 찾았습니다 . 문제는 tintColor속성에 대해 밝은 색상을 선택 하면 선택한 세그먼트가 거의 인식 할 수 없게된다는 것입니다 (그 색상은 나머지 세그먼트 컨트롤과 거의 동일하므로 선택한 세그먼트와 선택되지 않은 세그먼트를 구분하기가 어렵습니다). 그래서 세분화 된 제어를 위해 좋은 밝은 색상을 사용할 수 없습니다. 솔루션은 선택한 세그먼트 색상에 대한 별도의 속성이지만 찾을 수 없습니다. 누구든지 이것을 해결 했습니까?


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

나를 위해 작동하는지 확인


선택한 세그먼트 를 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 단계는 인터페이스 빌더 또는 표시된대로 코드에서 수행 할 수 있습니다. 그러나 3 단계는 코드에서만 수행 할 수 있습니다.
  • 이 "123.0 / 255.0"과 같은 표기법으로 설정되는 색상 값은 UIColor에서 요구하는 정규화 된 부동 소수점 값 대신 RGB 값을 돋보이게하는 방법입니다 (원하는 경우 무시하십시오).

이렇게하려면 세그먼트 화 된 컨트롤의 하위보기를 반복하고 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];
    });

어떤 이유로 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];

이것이 도움이 되었기를 바랍니다.

Seb Kade "도움이 필요합니다"


편집 :이 솔루션은 iOS 6에서 작동하지 않습니다. 아래 David Thompson의 답변을 참조하십시오.

이 스레드는 정말 오래되었지만 간단한 답변이 제대로 작동하지 않았습니다.

허용되는 대답은 선택 취소 된 세그먼트 컨트롤의 색상을 되 돌리는 한 작동합니다. 다음과 같은 것이 값 변경 기능에서 작동합니다.

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

다음은 uihacker의 CustomSegmentedControl의 수정 된 버전입니다 (댓글의 크레딧 참조). 아이디어는 selectedIndex를 사용하여 isSelected 메서드를 사용하여 tintColor가 변경되어야하는 하위 뷰를 찾는 방법을 변경하는 것입니다. 서브 뷰 순서가 무작위로 변경되는 3 개 이상의 세그먼트가있는 사용자 정의 UISegmentedControl로 작업했기 때문입니다 (uihacker의 "hasSetSelectedIndexOnce"플래그도이 문제를 해결하지 않습니다!). 코드는 아직 초기 개발 단계에 있으므로 위험을 감수하고 사용하십시오. 모든 의견을 환영합니다 :)

또한 인터페이스 빌더에 대한 지원을 추가하고 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

이것이 앱 스토어에서 승인되는지 확실하지 않지만 UISegmentedControl에 하위 클래스를 작성하여 사용자 지정 선택 및 선택 취소 색상을 설정할 수 있습니다. 자세한 내용은 참고 사항을 확인하십시오.

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


@jothikenpachi가 위에서 제공 한 답변을 명확히하기 위해 다음 UISegmentController 카테고리가 iOS6에서 잘 작동하고 세그먼트에서 임의의 on / off 색상 체계를 허용한다는 것을 알았습니다. 또한 개인 메서드 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"를 설정해보십시오.


iOS 6과 다르게 작동하는 iOS 7에서이 문제가 발생했습니다.

iOS 7에서 선택한 세그먼트의 레이블 색상은 UISegementControl 배경과 동일한 색상입니다. iOS 7에서 변경하는 유일한 방법은 UISegmentControl의 배경색을 설정하는 것입니다.

segmentControl.backgroundColor = customColor;

이것을 사용하십시오 :

[[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected];

나는 이것을 사용하고 모든 색상을 한 번에 변경했습니다.

mySegmentedControl.tintColor = [UIColor redColor]

세그먼트와 동일한 인덱스로 하위 뷰에 태그를 사용할 수 있으므로 순서에 관계없이 세그먼트가 올바르게 색상이 지정됩니다.

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

세그먼트 사이를 전환 할 때 상위 두 가지 솔루션이 작동하지 않았습니다.

내 솔루션은 내 뷰 컨트롤러에서 세그먼트 변경 이벤트를 처리 한 다음 세그먼트가 변경 될 때마다이 메서드를 호출하는 것입니다.

+ (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];
    }    
}

왜 아무도 언급하지 않았는지 궁금합니다. UIAppearanceProxy

Apple 문서 ::

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

Call From : 이 메소드를 AppDelegatefrom에서 호출 할 수 있습니다 .

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


당신의 일을하기 위해, 문서화되지 않은 기능과 해킹에 접근해야 할 수도 있습니다. 이것은 확실히 애플을 화나게 만들고 당신의 애플리케이션이 거부 될 수도 있습니다.

이제 해결책은 두 개의 버튼을 대신 사용하고 클릭 할 때 이미지를 바꾸는 다른 트릭에 있습니다. 버튼을 더 가깝게 유지하고 절반으로 분할 된 컨트롤의 이미지를 유지하여 분할 된 컨트롤의 환상을 제공합니다. 이것이 제가 제안 할 수있는 전부입니다.

도움이 되었기를 바랍니다.

감사,

Madhup


각 세그먼트에 태그를 지정한 다음 태그에 대해 TintColor를 설정할 수 있습니다.

#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];  

위의 답변이 매우 유용하다는 것을 알았습니다. 세그먼트 컨트롤을 사용하여 노브의 정밀도를 설정하고 있습니다. 나는 위의 답변을 혼합하여 이것을 생각해 냈습니다.

-(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];


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

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.

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

[segmentedControl setSelectedSegmentTintColor:[UIColor darkGrayColor]];

//For iOS 13

이 Swift 4 코드는 나를 위해 작동합니다.

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)

참고 URL : https://stackoverflow.com/questions/2270526/uisegmentedcontrol-selected-segment-color

반응형