web-dev-qa-db-fra.com

Changer la couleur de la bordure UIButton en surbrillance

J'ai un simple UIButton personnalisé, auquel j'ai ajouté:

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

Cependant, je veux changer le .bordercolor lorsque le bouton est en surbrillance. J'ai essayé d'ajouter une action à l'action touchDown du bouton qui change le .bordercolor en rouge, mais lorsque l'utilisateur lève le doigt, il reste rouge plutôt que de revenir au bleu. Des idées?

23
JohnWickham

Vous étiez sur la bonne voie. Vérifiez le code ci-dessous, il développe, mais ce que vous voudrez faire est de relier les sélecteurs aux différents événements de contrôle de votre bouton. Un pour touchDown pour changer l'ombre en rouge et un autre pour touchUpInside pour rétablir l'ombre lorsque vous levez le doigt.

De plus, je vois que vous avez posé plusieurs questions sur le dépassement de capacité et que vous n’avez pas encore indiqué de réponse correcte. Pour continuer à recevoir de l'aide sur ce site Web, vous devrez commencer à noter les réponses correctes à vos questions.

[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:Les autres options pour UIControlEvents incluent:

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
};
40
Mick MacCallum

Le Swift 2.x répond à votre problème:

Remplacez simplement la propriété mise en surbrillance par l'observateur "didSet".

override var highlighted: Bool {
    didSet {

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

Swift 3:

override var isHighlighted: Bool {
    didSet {

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

Vous pouvez remplacer les méthodes setHighlighted et setSelected dans la sous-classe UIButton. À partir de là, il vous suffit de modifier la couleur de la bordure comme suit:

- (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];
    }
}
9
Josip B.

Solution autonome: 

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

Merci à @ josip-b!

2
Zorayr

Pour une solution n'impliquant pas de sous-classement, vous pouvez toujours ajouter une méthode d'extension à UIButton. Par exemple.

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

    UIGraphicsBeginImageContext(bounds.size)
    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)
}
1
chrysAllwood

Swift 4 :

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