在突出显示时更改UIButton边框颜色

时间:2022-11-21 15:00:13

I've got a simple custom UIButton, to which I added:

我有一个简单的自定义UIButton,我添加了:

button.layer.bordercolor = [[UIColor blueColor]CGColor];

However, I want to change the .bordercolor when the button is highlighted. I tried adding an action to the button's touchDown action that changes the .bordercolor to red, but when the user lifts their finger, it stays red rather than returning to blue. Any ideas?

但是,我想在突出显示按钮时更改.bordercolor。我尝试在按钮的touchDown动作中添加动作,将.bordercolor更改为红色,但是当用户抬起手指时,它会保持红色而不是返回蓝色。有任何想法吗?

6 个解决方案

#1


37  

You were on the right track. Check the code below, it elaborates on this, but what you'll want to do is link selectors to different control events on your button. One for touchDown to change the shadow to red, and another for touchUpInside to change the shadow back when you lift your finger.

你走在正确的轨道上。检查下面的代码,它详细说明了这一点,但您要做的是将选择器链接到按钮上的不同控件事件。一个用于touchDown将阴影更改为红色,另一个用于touchUpInside以在您抬起手指时更改阴影。

Additionally, I see you've asked several questions on Stack Overflow and have yet to mark any as the correct answer. To continue to receive help on this website, you will need to start marking correct answers to your questions.

另外,我看到你已经在Stack Overflow上提出了几个问题,并且尚未将其标记为正确的答案。要继续在本网站上获得帮助,您需要开始标记问题的正确答案。

[myButton addTarget:self action:@selector(highlightBorder) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(unhighlightBorder) forControlEvents:UIControlEventTouchUpInside];


- (void)highlightBorder
{
    myButton.layer.borderColor = [[UIColor redColor]CGColor];
}

- (void)unhighlightBorder
{
    myButton.layer.borderColor = [[UIColor blueColor]CGColor];
    //additional code for an action when the button is released can go here.
}

NOTE: Other options for UIControlEvents include:

注意:UIControlEvents的其他选项包括:

enum {
   UIControlEventTouchDown           = 1 <<  0,
   UIControlEventTouchDownRepeat     = 1 <<  1,
   UIControlEventTouchDragInside     = 1 <<  2,
   UIControlEventTouchDragOutside    = 1 <<  3,
   UIControlEventTouchDragEnter      = 1 <<  4,
   UIControlEventTouchDragExit       = 1 <<  5,
   UIControlEventTouchUpInside       = 1 <<  6,
   UIControlEventTouchUpOutside      = 1 <<  7,
   UIControlEventTouchCancel         = 1 <<  8,

   UIControlEventValueChanged        = 1 << 12,

   UIControlEventEditingDidBegin     = 1 << 16,
   UIControlEventEditingChanged      = 1 << 17,
   UIControlEventEditingDidEnd       = 1 << 18,
   UIControlEventEditingDidEndOnExit = 1 << 19,

   UIControlEventAllTouchEvents      = 0x00000FFF,
   UIControlEventAllEditingEvents    = 0x000F0000,
   UIControlEventApplicationReserved = 0x0F000000,
   UIControlEventSystemReserved      = 0xF0000000,
   UIControlEventAllEvents           = 0xFFFFFFFF
};

#2


9  

You can override setHighlighted and setSelected methods in UIButton subclass. From there you just tweak border color like following:

您可以覆盖UIButton子类中的setHighlighted和setSelected方法。从那里你只需调整边框颜色如下:

- (void)setHighlighted:(BOOL)highlighted {

    [super setHighlighted:highlighted];

    [self tweakState:highlighted];
}

- (void)setSelected:(BOOL)selected {

    [super setSelected:selected];

    [self tweakState:selected];
}

- (void)tweakState:(BOOL)state {

    if (state) {
        self.layer.borderColor = [_highlightedBorderColor CGColor];
    }
    else {
        self.layer.borderColor = [_defaultBorderColor CGColor];
    }
}

#3


9  

The SWIFT 2.x answer to your problem:

SWIFT 2.x回答您的问题:

➜ Just override the highlighted property with "didSet" observer.

➜用“didSet”观察者覆盖突出显示的属性。

override var highlighted: Bool {
    didSet {

        switch highlighted {
        case true:
            layer.borderColor = UIColor.lightGrayColor().CGColor
        case false:
            layer.borderColor = UIColor.blackColor().CGColor
        }
    }
}

Swift 3:

斯威夫特3:

override var isHighlighted: Bool {
    didSet {

        switch isHighlighted {
        case true:
            layer.borderColor = UIColor.lightGray.cgColor
        case false:
            layer.borderColor = UIColor.black.cgColor
        }
    }
}

#4


2  

Self contained solution:

自包含解决方案:

static UIColor *BorderColor()
{
  return [UIColor grayColor];
}

static UIColor *HighlightedBorderColor()
{
  return [UIColor lightGrayColor];
}

@interface BorderedButton : UIButton

@end

@implementation BorderedButton

- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
    self.layer.borderColor = BorderColor().CGColor;
    self.layer.cornerRadius = 4.0;
    self.layer.borderWidth = 1.0;
  }
  return self;
}

- (void)setHighlighted:(BOOL)highlighted
{
  [super setHighlighted:highlighted];
  self.layer.borderColor = (highlighted) ? HighlightedBorderColor().CGColor : BorderColor().CGColor;
}

@end

Thanks to @josip-b!

感谢@ josip-b!

#5


0  

For a solution that doesn't involve subclassing, you could always add an extension method to UIButton. E.g.

对于不涉及子类化的解决方案,您始终可以向UIButton添加扩展方法。例如。

func setBackgroundColor(_ backgroundColor: UIColor,
                        borderColor: UIColor,
                        borderWidth: CGFloat,
                        cornerRadius: CGFloat,
                        forState state: UIControlState) {

    UIGraphicsBeginImageContext(CGSize(width: bounds.size.width, height: bounds.size.height))
    guard let context = UIGraphicsGetCurrentContext() else { return }

    if borderWidth > 0 {
        layer.borderWidth = 0 // hide the layer's border if we're going to draw a border
    }

    context.addPath(UIBezierPath(roundedRect: bounds.insetBy(dx: borderWidth, dy: borderWidth), cornerRadius: cornerRadius).cgPath)
    context.setStrokeColor(borderColor.cgColor)
    context.setFillColor(backgroundColor.cgColor)
    context.setLineWidth(borderWidth)

    context.closePath()
    context.strokePath()
    context.fillPath()

    let buttonImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    setBackgroundImage(buttonImage, for: state)
}

#6


0  

Swift 4 :

斯威夫特4:

override var isHighlighted: Bool {
    didSet {
        layer.borderColor = isHighlighted ? UIColor.lightGray.cgColor : UIColor.black.cgColor
    }
}

#1


37  

You were on the right track. Check the code below, it elaborates on this, but what you'll want to do is link selectors to different control events on your button. One for touchDown to change the shadow to red, and another for touchUpInside to change the shadow back when you lift your finger.

你走在正确的轨道上。检查下面的代码,它详细说明了这一点,但您要做的是将选择器链接到按钮上的不同控件事件。一个用于touchDown将阴影更改为红色,另一个用于touchUpInside以在您抬起手指时更改阴影。

Additionally, I see you've asked several questions on Stack Overflow and have yet to mark any as the correct answer. To continue to receive help on this website, you will need to start marking correct answers to your questions.

另外,我看到你已经在Stack Overflow上提出了几个问题,并且尚未将其标记为正确的答案。要继续在本网站上获得帮助,您需要开始标记问题的正确答案。

[myButton addTarget:self action:@selector(highlightBorder) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(unhighlightBorder) forControlEvents:UIControlEventTouchUpInside];


- (void)highlightBorder
{
    myButton.layer.borderColor = [[UIColor redColor]CGColor];
}

- (void)unhighlightBorder
{
    myButton.layer.borderColor = [[UIColor blueColor]CGColor];
    //additional code for an action when the button is released can go here.
}

NOTE: Other options for UIControlEvents include:

注意:UIControlEvents的其他选项包括:

enum {
   UIControlEventTouchDown           = 1 <<  0,
   UIControlEventTouchDownRepeat     = 1 <<  1,
   UIControlEventTouchDragInside     = 1 <<  2,
   UIControlEventTouchDragOutside    = 1 <<  3,
   UIControlEventTouchDragEnter      = 1 <<  4,
   UIControlEventTouchDragExit       = 1 <<  5,
   UIControlEventTouchUpInside       = 1 <<  6,
   UIControlEventTouchUpOutside      = 1 <<  7,
   UIControlEventTouchCancel         = 1 <<  8,

   UIControlEventValueChanged        = 1 << 12,

   UIControlEventEditingDidBegin     = 1 << 16,
   UIControlEventEditingChanged      = 1 << 17,
   UIControlEventEditingDidEnd       = 1 << 18,
   UIControlEventEditingDidEndOnExit = 1 << 19,

   UIControlEventAllTouchEvents      = 0x00000FFF,
   UIControlEventAllEditingEvents    = 0x000F0000,
   UIControlEventApplicationReserved = 0x0F000000,
   UIControlEventSystemReserved      = 0xF0000000,
   UIControlEventAllEvents           = 0xFFFFFFFF
};

#2


9  

You can override setHighlighted and setSelected methods in UIButton subclass. From there you just tweak border color like following:

您可以覆盖UIButton子类中的setHighlighted和setSelected方法。从那里你只需调整边框颜色如下:

- (void)setHighlighted:(BOOL)highlighted {

    [super setHighlighted:highlighted];

    [self tweakState:highlighted];
}

- (void)setSelected:(BOOL)selected {

    [super setSelected:selected];

    [self tweakState:selected];
}

- (void)tweakState:(BOOL)state {

    if (state) {
        self.layer.borderColor = [_highlightedBorderColor CGColor];
    }
    else {
        self.layer.borderColor = [_defaultBorderColor CGColor];
    }
}

#3


9  

The SWIFT 2.x answer to your problem:

SWIFT 2.x回答您的问题:

➜ Just override the highlighted property with "didSet" observer.

➜用“didSet”观察者覆盖突出显示的属性。

override var highlighted: Bool {
    didSet {

        switch highlighted {
        case true:
            layer.borderColor = UIColor.lightGrayColor().CGColor
        case false:
            layer.borderColor = UIColor.blackColor().CGColor
        }
    }
}

Swift 3:

斯威夫特3:

override var isHighlighted: Bool {
    didSet {

        switch isHighlighted {
        case true:
            layer.borderColor = UIColor.lightGray.cgColor
        case false:
            layer.borderColor = UIColor.black.cgColor
        }
    }
}

#4


2  

Self contained solution:

自包含解决方案:

static UIColor *BorderColor()
{
  return [UIColor grayColor];
}

static UIColor *HighlightedBorderColor()
{
  return [UIColor lightGrayColor];
}

@interface BorderedButton : UIButton

@end

@implementation BorderedButton

- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
    self.layer.borderColor = BorderColor().CGColor;
    self.layer.cornerRadius = 4.0;
    self.layer.borderWidth = 1.0;
  }
  return self;
}

- (void)setHighlighted:(BOOL)highlighted
{
  [super setHighlighted:highlighted];
  self.layer.borderColor = (highlighted) ? HighlightedBorderColor().CGColor : BorderColor().CGColor;
}

@end

Thanks to @josip-b!

感谢@ josip-b!

#5


0  

For a solution that doesn't involve subclassing, you could always add an extension method to UIButton. E.g.

对于不涉及子类化的解决方案,您始终可以向UIButton添加扩展方法。例如。

func setBackgroundColor(_ backgroundColor: UIColor,
                        borderColor: UIColor,
                        borderWidth: CGFloat,
                        cornerRadius: CGFloat,
                        forState state: UIControlState) {

    UIGraphicsBeginImageContext(CGSize(width: bounds.size.width, height: bounds.size.height))
    guard let context = UIGraphicsGetCurrentContext() else { return }

    if borderWidth > 0 {
        layer.borderWidth = 0 // hide the layer's border if we're going to draw a border
    }

    context.addPath(UIBezierPath(roundedRect: bounds.insetBy(dx: borderWidth, dy: borderWidth), cornerRadius: cornerRadius).cgPath)
    context.setStrokeColor(borderColor.cgColor)
    context.setFillColor(backgroundColor.cgColor)
    context.setLineWidth(borderWidth)

    context.closePath()
    context.strokePath()
    context.fillPath()

    let buttonImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    setBackgroundImage(buttonImage, for: state)
}

#6


0  

Swift 4 :

斯威夫特4:

override var isHighlighted: Bool {
    didSet {
        layer.borderColor = isHighlighted ? UIColor.lightGray.cgColor : UIColor.black.cgColor
    }
}