inorganik inorganik -4 years ago 113
iOS Question

Best way to wire up a PaintCode button?

I have created a custom button in PaintCode. PC has lots of documentation on creating graphics, but not using them.

My method works but it has problems which I'll get to... I went the route of subclassing a UIButton which I placed in my storyboard. I then assigned it the class of my custom button, we'll call it

customButton
. Using this method you can connect an action in IB, and the highlighted state is handled by the
touchesBegan
and
touchesEnded
methods in tandem with a variable that toggles the highlighted view, but the problem is, the highlighted state is never displayed on quick touches.

customButton.m
:

@interface customButton ()

@property BOOL isPressed;

@end

@implementation customButton

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}

-(void) awakeFromNib {
[super awakeFromNib];
_buttonText = @"Post";
}

- (void)drawRect:(CGRect)rect
{
[StyleKit drawCustomButtonWithFrame:rect pressed:_isPressed buttonText:_buttonText];
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
_isPressed = YES;
[self setNeedsDisplay];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
_isPressed = NO;
[self setNeedsDisplay];
}


My question: is there a better way to implement a button drawn with PaintCode? The issue with this one is that it doesn't always display the highlighted state, and feels kinda hacky. Surely there's a better way?

Answer Source

The best way to go about this is to override the highlighted property in UIControl. It is the most accurate indicator of the button's state. I am using swift, but it's trivial to translate to ObjC:

class VectorizedButton: UIButton {
    override var highlighted: Bool {
        didSet {
            setNeedsDisplay()
        }
    }
}

Now, instead of passing in _isPressed, just pass in highlighted (or [self highlighted]).

For the sake of completeness:

- (void)setHighlighted:(BOOL)isHigh
{
    [super setHighlighted:isHigh];
    [self setNeedsDisplay];
}

It seems there is a good article about this here.


Complete code sample:

NOTE I took it a step further, and highlight if the button is not enabled or highlighted.

class VectorizedButton: UIButton {

    override var highlighted: Bool {
        didSet {
            setNeedsDisplay()
        }
    }

    // MARK: - Init & Dealloc

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        backgroundColor = UIColor.clearColor()
    }

    // MARK: - Private methods

    private var shouldHighlight: Bool {
        return highlighted || !enabled
    }

    // MARK: - Public methods

    override func drawRect(rect: CGRect) {
        StyleKit.drawMyButton(frame: bounds, highlighted: shouldHighlight)
    }

}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download