2013-10-06 124 views
6

這是一個非常奇怪的過程。UIButton的標題顏色在突出顯示/選中時不會改變,但背景顏色將會變爲

我有一個IBOutletCollection的UIButtons。通過收集我環路和創建它們像這樣(的displayHourButtonsviewWillAppear叫):

- (void)displayHourButtons 
{ 
    // Counter 
    NSUInteger b = 0; 

    // Set attributes 
    UIFont *btnFont = [UIFont fontWithName:@"Metric-Semibold" size:13.0]; 
    UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) green:(147/255.0f) blue:(147/255.0f) alpha:1.0]; 
    NSNumber *btnTracking = [NSNumber numberWithFloat:0.25]; 
    NSMutableParagraphStyle *btnStyle = [[NSMutableParagraphStyle alloc] init]; 
    [btnStyle setLineSpacing:2.0]; 

    NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys: 
           btnFont, NSFontAttributeName, 
           btnTextColor, NSForegroundColorAttributeName, 
           btnTracking, NSKernAttributeName, nil]; 

    // CREATE THE BUTTONS 
    for (UIButton *hourButton in hourButtons) { 
      // I'm using the attributed string for something else 
      // later in development that I haven't got to yet. 
      // I simplified the string for this example's sake. 
     NSString *btnTitleText = [NSString stringWithFormat:@"Button %lu", (unsigned long)b]; 

     NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] 
                initWithString:btnTitleText 
                attributes:btnAttrs]; 

     [attributedText addAttribute:NSParagraphStyleAttributeName 
           value:btnStyle 
           range:NSMakeRange(0, btnTitleText.length)]; 


     CALayer *btnLayer = [hourButton layer]; 
     [btnLayer setMasksToBounds:YES]; 
     [btnLayer setCornerRadius:19.0f]; 
     [hourButton setTag:b]; 
     [hourButton setContentEdgeInsets:UIEdgeInsetsMake(5.0, 1.0, 0.0, 0.0)]; 
     [hourButton setAttributedTitle:attributedText forState:UIControlStateNormal]; 
     [hourButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter]; 
     [hourButton setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter]; 
     hourButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
     [hourButton addTarget:self action:@selector(showHour:) forControlEvents:UIControlEventTouchUpInside]; 

     b++; 
    } 
} 

當點擊一個按鈕,每個動作showHour:被稱爲:

- (IBAction)showHour:(id)sender 
{ 
    [self.hourButtons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     UIButton *button = (UIButton *)obj; 

     if (button != sender && button.enabled) { 
       // This is applied. I know because I tested it with redColor 
      [button setBackgroundColor:[UIColor clearColor]]; 

      // Doesn't change, stays the gray set initially 
      [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 
     } 
     else { 
       // This is applied 
      [button setBackgroundColor:[UIColor colorWithRed:(169/255.0f) green:(234/255.0f) blue:(255/255.0f) alpha:1.0]]; 

      // This is not 
      [button setTitleColor:[UIColor whiteColor] forState:(UIControlStateNormal | UIControlStateSelected | UIControlStateHighlighted)]; 
     } 
    }]; 

    // displayHour uses the tag to change labels, images, etc. 
    [self displayHour:(long int)[sender tag]]; 
} 

我試着各種瘋狂的事情讓UIImage處於選定狀態,但沒有任何工作。這枚枚舉對象是唯一有效的工作。這就是爲什麼我說這是一個奇怪的過程。我猜按鈕不會無限期地保持活動狀態?

反正,我的問題:爲什麼標題顏色沒有改變是否有某種原因?只是背景?我懷疑它與最初沒有設置的背景有關,但我無法解釋爲什麼。

謝謝!

修訂

每@Timothy駝鹿的回答,下面是更新的代碼。

- (IBAction)showHour:(id)sender 
{ 
    [self.hourButtons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     UIButton *button = (UIButton *)obj; 

     // Grab the mutable string from the button and make a mutable copy 
     NSMutableAttributedString *attributedText = [[button attributedTitleForState:UIControlStateNormal] mutableCopy]; 

     // Shared attribute styles 
     UIFont *btnFont = [UIFont fontWithName:@"Metric-Semibold" size:14.0]; 
     NSNumber *btnTracking = [NSNumber numberWithFloat:0.25]; 
     NSMutableParagraphStyle *btnStyle = [[NSMutableParagraphStyle alloc] init]; 
     [btnStyle setLineSpacing:2.0]; 

     // Since we can't set a color directly on a Attributed string we have 
     // to make a new attributed string. 
     if (button != sender && button.enabled) { 
      // Return to the default color 
      UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) green:(147/255.0f) blue:(147/255.0f) alpha:1.0]; 

      // Set up attributes 
      NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys: 
             btnFont, NSFontAttributeName, 
             btnTextColor, NSForegroundColorAttributeName, 
             btnTracking, NSKernAttributeName, nil]; 

      // Reapply the default color (for the one button that was changed to white) 
      [attributedText setAttributes:btnAttrs 
            range:NSMakeRange(0, attributedText.length)]; 

      // Add line-height 
      [attributedText addAttribute:NSParagraphStyleAttributeName 
            value:btnStyle 
            range:NSMakeRange(0, attributedText.length)]; 

      // Reset default attributes 
      [button setBackgroundColor:[UIColor clearColor]]; 
      [button setAttributedTitle:attributedText forState:UIControlStateNormal]; 
     } 
     else { 
      // Our new white color for the active button 
      UIColor *btnTextColor = [UIColor whiteColor]; 

      // Set up attributes 
      NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys: 
             btnFont, NSFontAttributeName, 
             btnTextColor, NSForegroundColorAttributeName, 
             btnTracking, NSKernAttributeName, nil]; 

      // Apply our new white color 
      [attributedText setAttributes:btnAttrs 
            range:NSMakeRange(0, attributedText.length)]; 

      // Add line-height 
      [attributedText addAttribute:NSParagraphStyleAttributeName 
            value:btnStyle 
            range:NSMakeRange(0, attributedText.length)]; 

      // Add new attributes for active button 
      [button setBackgroundColor:[UIColor colorWithRed:(169/255.0f) green:(234/255.0f) blue:(255/255.0f) alpha:1.0]]; 
      [button setAttributedTitle:attributedText forState:UIControlStateNormal]; 
     } 
    }]; 

    [self displayHour:(long int)[sender tag]]; 
} 

回答

16

setTitleColor在標題是屬性字符串時不起作用。將所需顏色應用到屬性字符串後,可以使用普通的NSString或再次撥打setAttributedTitle

+0

是的,就是這樣。謝謝! –

-2

我立即注意到了這一點。簡單的錯誤可能:)

變化

UIColor *btnTextColor = [UIColor colorWithRed:(147/255.f) 
             green:(147/255.f) 
             blue:(147/255.f) alpha:1.0]; 

UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) 
             green:(147/255.0f) 
             blue:(147/255.0f) alpha:1.0]; 

它不改變的原因可能是因爲它沒有認識到UIColor,因爲你沒有因爲它看到(147/255)而不是(147/255.0)

+0

這絕對是個錯誤,謝謝。但是,我修復顏色值後仍然遇到同樣的問題。他們保持原來設置的淺灰色,而不是變成白色。儘管如此,我已經使用顏色修正更新了原始代碼。 –

+0

爲什麼不設置文本顏色爲(UButton * hourButton in hourButtons)循環?這樣,它找到按鈕...只是做[hourButton setTitleColor:btnTextColor forState:UIControlStateNormal];測試它,然後將狀態更改爲您以後需要的任何其他狀態 – user2277872

+0

嘿,請參閱上面的答案。這是因爲我使用了一個屬性字符串。 –

14

此外它是非常重要的沒有系統風格的按鈕,只是把它放在自定義... 這是用於類似的問題,而不是這個特定的問題。

+2

系統樣式按鈕和自定義樣式按鈕之間的區別究竟是什麼?文檔在這方面似乎含糊不清。例如,使其定製樣式將刪除用作文本顏色的tintColor。還有什麼其他差異?謝謝。 – trss

+1

這實際上是一個**非常重要的提示**,感謝Catalin!桁架,似乎有許多細微的差異。例如,有(煩人的!)沒有關於TEXT的等價函數,用於adjustsImageWhenHighlighted。實質上,您必須使用「自定義」來實現「adjustsTEXTWhenHighlighted = false」。和其他微妙的例子! – Fattie

+0

trss可能是繪製的方式和系統內部的一些內部錯誤最有可能 – Catalin

0

我創建了一個自定義類MyButtonUIButton擴展。然後Identity Inspector裏面添加了這個:

enter image description here

在此之後,按鈕類型更改爲定製

enter image description here

然後你可以設置屬性,如textColorUIFontUIButton爲不同的狀態:

enter image description here

然後,我還創建了內部MyButton類兩種方法,我有我的代碼裏面打電話的時候,我想UIButton所強調的要顯示的:

- (void)changeColorAsUnselection{ 
    [self setTitleColor:[UIColor colorFromHexString:acColorGreyDark] 
       forState:UIControlStateNormal & 
         UIControlStateSelected & 
         UIControlStateHighlighted]; 
} 

- (void)changeColorAsSelection{ 
    [self setTitleColor:[UIColor colorFromHexString:acColorYellow] 
       forState:UIControlStateNormal & 
         UIControlStateHighlighted & 
         UIControlStateSelected]; 
} 

您必須設置titleColor正常,亮點並選擇UIControlState,因爲根據UIControlState的文檔,一次可以有多個狀態。 如果您不創建這些方法,UIButton將顯示選擇或突出顯示,但它們不會保留在您在UIInterface Builder內部設置的UIColor,因爲它們僅用於顯示選擇的簡短顯示,而不用於顯示選擇本身。

+1

是不是應該是一個OR而不是AND – accfews

+0

在這種情況下,您必須將其設置爲所有這些狀態,因爲按鈕有這麼多。否則,它可能會改變這些狀態之一的顏色,最後它會頻繁地改變顏色,看起來像一個錯誤。也可能這個解決方案只適用於我有的問題。 –

0

就我而言,我使用的是XCode 7.x.

我遇到過類似的問題。使用NSAttributedString

let underlineAttribute = [NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue] 
     let underlineAttributedString = NSAttributedString(string: "FILTER", attributes: underlineAttribute) 
     filterButton.setTitleColor(AppConfig.FOREGROUND, forState: .Normal) 
     filterButton.setAttributedTitle(underlineAttributedString, forState: .Normal) 

後filterButton.setTitleColor(AppConfig.FOREGROUND,forState:。正常)沒有得到實現。

我改變了Interface Builder中按鈕的色調(默認爲淺藍色)。現在,它適用於我。

0

上述答案的替代方法是使用字符串屬性應用文本顏色。您可以爲每個控件狀態設置不同的NSAttributedString,所以這可以達到相同的效果 - 按鈕文本將在選擇/高亮顯示時更改顏色。

例子:

// We're assuming attributedString already exists - this is your completed attributed string so far 
// We're going to copy this string into two more NS(Mutable)AttributedString variables - one for the "normal" state and one for the "highlighted" state 
NSMutableAttributedString *normalAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString]; 
// Set the desired foreground color (in this case it's for the "normal" state) for the length of the string 
[normalAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0,attributedString.length)]; 

// Rinse and repeat for the highlighted state 
NSMutableAttributedString *highlightedAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString]; 
[highlightedAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0,attributedString.length)]; 

// Finally, we'll set these as the attributedTitles for the relevant control states. 
[myButton setAttributedTitle:normalAttributedString forState:UIControlStateNormal]; 
[myButton setAttributedTitle:highlightedAttributedString forState:UIControlStateSelected]; 
[myButton setAttributedTitle:highlightedAttributedString forState:UIControlStateHighlighted];