简体   繁体   English

Objective-C在选中/未选中时突出显示UIButton

[英]Objective-C highlight UIButton when selected / unselected

I have a UIButton inside a UIView, when the UIButton is selected I would like have a background colour of dark gray...is this possible? 我在UIView里面有一个UIButton,当选择UIButton时,我想要一个深灰色的背景颜色......这可能吗?

UIView *toolbar = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 40, 160)];
    [toolbar setBackgroundColor:[UIColor colorWithWhite: 0.70 alpha:0.5]];

    toolbar.layer.cornerRadius = 5;

    UIButton *penTool = [UIButton buttonWithType:UIButtonTypeCustom];
    penTool.frame = CGRectMake(5, 0, 30, 30);
    [penTool setImage:[UIImage imageNamed:@"pen-but" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
    [penTool addTarget:self action:@selector(drawButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    penTool.autoresizingMask = UIViewAutoresizingNone;
    penTool.exclusiveTouch = YES;
    penTool.tag = 1;

    [toolbar addSubview:penTool];

What if you can do this? 如果你能这样做怎么办?

[button setBackgroundColor:[UIColor greenColor] 
                  forState:UIControlStateSelected];

Let's give a great API for every state, not just selected, just like UIButton default API's ability to change image and title for every state. 让我们为每个州提供一个很好的API,而不仅仅是选择,就像UIButton默认API更改每个州的图像和标题一样。

BGButton.h BGButton.h

#import <UIKit/UIKit.h>

@interface BGButton : UIButton

- (void)setBackgroundColor:(UIColor *)backgroundColor 
                  forState:(UIControlState)state;

@end

BGButton.m BGButton.m

#import "BGButton.h"

@implementation BGButton {
    NSMutableDictionary *_stateBackgroundColor;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _stateBackgroundColor = [[NSMutableDictionary alloc] init];
    }
    return self;
}


- (void)setBackgroundColor:(UIColor *)backgroundColor {
    [super setBackgroundColor:backgroundColor];

   /*
    * If user set button.backgroundColor we will set it to 
    * normal state's backgroundColor.
    * Check if state is on normal state to prevent background being 
    * changed for incorrect state when updateBackgroundColor method is called.
    */
    if (self.state == UIControlStateNormal) {
        [self setBackgroundColor:backgroundColor forState:UIControlStateNormal];
    }
}

- (void)setBackgroundColor:(UIColor *)backgroundColor 
                  forState:(UIControlState)state {
    NSNumber *key = [NSNumber numberWithInt:state];
    [_stateBackgroundColor setObject:backgroundColor forKey:key];
}

/*
 * state is synthesized from other flags. So we can't use KVO 
 * to listen for state changes.
 */
- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    [self stateDidChange];
}

- (void)setEnabled:(BOOL)enabled {
    [super setEnabled:enabled];
    [self stateDidChange];
}

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];
    [self stateDidChange];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [self stateDidChange];
}

- (void)stateDidChange {
    [self updateBackgroundColor];
}

- (void)updateBackgroundColor {
    NSNumber *key = [NSNumber numberWithInt:self.state];
    self.backgroundColor = [_stateBackgroundColor objectForKey:key];
}

@end


You can use it like the default UIButton API 您可以像默认的UIButton API一样使用它

BGButton *button = [[BGButton alloc] init];

[button setBackgroundColor:[UIColor greenColor] 
                  forState:UIControlStateSelected];

[button setBackgroundColor:[UIColor blueColor] 
                  forState:UIControlStateHighlighted];

[button setBackgroundColor:[UIColor orangeColor] 
                  forState:UIControlStateDisabled];

Even if you use 即使你使用

button.backgroundColor = [UIColor redColor];

You will stay safe, it will be translated into 你将保持安全,它将被翻译成

[button setBackgroundColor:[UIColor redColor] 
                  forState:UIControlStateNormal];

if you have this code 如果你有这个代码

[self.view addSubview:toolbar];

then just implement your button selector 然后只需实现你的按钮选择器

-(void)drawButtonTapped:(UIButton*)button{

if (button.selected) {
    button.backgroundColor = [UIColor clearColor];
    button.selected = NO;
}else{
    button.backgroundColor = [UIColor darkGrayColor];
    button.selected = YES;
}
}

I don't know why guys would go through such trouble when we have this functionality built-in inside UIButton . 我不知道为什么当我们在UIButton内置这个功能时,人们会遇到这样的麻烦。 All you need to do is use UIButtonTypeSystem That's all. 您需要做的就是使用UIButtonTypeSystem这就是全部。

[UIButton buttonWithType:UIButtonTypeSystem]

Seriously, there's nothing more to it. 说真的,没有别的了。 Have a look at it's behavior in the screenshots. 看一下屏幕截图中的行为。

INTERFACE BUILDER 接口建设者

故事板

RUN TIME 运行

模拟器

Want to change color, set tintColor to color of your choice. 想要改变颜色,将tintColor设置为您选择的颜色。

ADVANTAGES 好处

  • Covers titles with dynamic lengths. 涵盖动态长度的标题。 Not applied on all button width. 不适用于所有按钮宽度。
  • When selected, title color is transparent, your background can be seen through, try to use an image as a background. 选中后,标题颜色是透明的,可以看到您的背景,尝试使用图像作为背景。

Let's hope you have at least iOS7 as deployment target. 我们希望您至少拥有iOS7作为部署目标。 UIButtonTypeSystem was introduce with revised UI design guidelines of iOS7 and has been there for almost 3 years. UIButtonTypeSystem引入了iOS7的修订UI设计指南,已经存在了近3年。

Good Luck! 祝好运!

I used a UIButton subclass here: 我在这里使用了一个UIButton子类:

#import "CustomButton.h"

@interface CustomButton()
@property (nonatomic,strong) UIColor *originalColor;
@end

@implementation CustomButton

- (void)didMoveToSuperview
{
    self.originalColor = self.superview.backgroundColor;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.superview.backgroundColor = [UIColor grayColor];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    if ([self hitTest:location withEvent:nil]) {
        self.superview.backgroundColor = [UIColor grayColor];
        self.originalColor = self.superview.backgroundColor;
    }
    else
    {
        self.superview.backgroundColor = self.originalColor;
    }
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.superview.backgroundColor = self.originalColor;    
}

@end

If you subclass your button from this class, It should give you the desired effect. 如果你从这个类中继承你的按钮,它应该给你想要的效果。 This also gives you the highlight effect. 这也为您提供了亮点效果。 If you wish you can disable it by removing the line on touchesBegan. 如果您希望可以通过删除touchesBegan上的行来禁用它。

Just try to Override the UIButton with the following Method... 只是尝试使用以下方法覆盖UIButton ...

   - (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];

    if (highlighted) {
        self.backgroundColor = [UIColor darkGray];
    }

}

I think you'll be want to change the selectedImage for flexibility not the background. 我想你会想要改变selectedImage的灵活性而不是背景。

Add another image (eg pen-but-selected ) in the project. 在项目中添加另一个图像(例如, pen-but-selected )。 Add this 2nd line for setImage: setImage:添加第二行setImage:

[penTool setImage:[UIImage imageNamed:@"pen-but-selected" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateSelected];

- (void)drawButtonTapped:(UIButton *)button {
    button.selected = !button.selected;
}

If you still want to change background color. 如果您仍想更改背景颜色。 @jamil's answer would work. @ jamil的答案会奏效。 Make sure the buttonImage has transparent part so you can see the buttonBackground through the buttonImage . 确保buttonImage具有透明部分,所以你可以看到buttonBackground通过buttonImage

Try using a boolean, or some other reference to the selection state of the button. 尝试使用布尔值或其他对按钮选择状态的引用。 You could also make use of a 'highlightColour' as well as the 'selectedColour' if you wanted closer control (should probably do this for better UX). 如果你想要更密切的控制(你应该这样做以获得更好的用户体验),你也可以使用'highlightColour'以及'selectedColour'。

bool buttonIsSelected = false;

UIColor * selectedColour = [UIColor redColor];
UIColor * defaultColour = [UIColor blueColor];

UIButton * button = [UIButton new];
button.frame = CGRectMake(0,0,100,100);
button.backgroundColor = [UIColor redColor];
[self.view addSubview:button];

[button addTarget:self action:@selector(buttonTouchUp:) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:@selector(buttonTouchCancel:) forControlEvents:UIControlEventTouchCancel];
[button addTarget:self action:@selector(buttonTouchDown:) forControlEvents:UIControlEventTouchDown];

-(void)buttonTouchUp:(UIButton *)button {

    if (buttonIsSelected){
        buttonIsSelected = false;
        button.backgroundColor = defaultColour;
    } else {
        buttonIsSelected = true;
        button.backgroundColor = selectedColour;
    }
}
-(void)buttonTouchCancel:(UIButton *)button {
    button.backgroundColor = defaultColour;        
    if (buttonIsSelected){
        button.backgroundColor = selectedColour;
    }
}
-(void)buttonTouchDown:(UIButton *)button {
    button.backgroundColor = selectedColour;
}
-(void)OnSelect:(UIButton*)button{

if (button.selected) {
    button.backgroundColor = [UIColor blue];
    button.selected = NO;
}else{
    button.backgroundColor = [UIColor darkGrayColor];
    button.selected = YES;
}
}

use the above this will work.. 使用上面这将工作..

-(void)buttonTapped:(UIButton*)button{ - (无效)buttonTapped:(的UIButton *)按钮{

button.selected =! button.selected;

if (button.selected)
    button.backgroundColor = [UIColor grayColor];

else
    button.backgroundColor = [UIColor clearColor];

} }

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

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