【问题标题】:Change UIButton border color on highlight在突出显示时更改 UIButton 边框颜色
【发布时间】:2012-08-12 23:45:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: iphone objective-c ios uibutton border-color


    【解决方案1】:

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

    此外,我看到您在 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.
    }
    

    注意: Other options for 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
    };
    

    【讨论】:

    • 谢谢,如果按钮接收到内部触摸动作,这将非常有效,但是如果用户通过将手指从按钮上拖动来取消触摸怎么办?知道我该如何处理吗?再次感谢!
    • @JohnWickham 当然,还有另一个名为 touchDragOutside 的触摸事件可能会解决问题。
    • 处理拖到外面,我发现这行得通:[button addTarget:self action:@selector(unhighlightBorder) forControlEvents:UIControlEventTouchCancel];
    • 要处理外部拖动,请使用 UIControlEventTouchDragExit
    【解决方案2】:

    SWIFT 2.x 解决您的问题:

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

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

    斯威夫特 3:

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

    【讨论】:

    • 轻量级和“快速风格”的解决方案 - 效果很好,谢谢!
    • if ... else 解决方案更适合这里。使用switch ... case 看起来太复杂了:)
    • 是的,不要使用案例 trye/false。在这些情况下,三元运算符是要走的路(请参阅 fethicas 答案)
    【解决方案3】:

    您可以覆盖 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];
        }
    }
    

    【讨论】:

      【解决方案4】:

      斯威夫特 4:

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

      【讨论】:

        【解决方案5】:

        独立解决方案:

        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
        

        感谢@josip-b!

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-01-09
          • 2013-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-13
          相关资源
          最近更新 更多