突出显示自定义UIButton

时间:2011-01-07 15:32:06

标签: iphone cocoa-touch uibutton

我正在构建的应用程序有很多自定义UIButton位于相当精确布局的图像之上。巴顿,控制图像和标签,以及你有什么,但有一个清晰的自定义风格的UIButton坐在它上面来处理水龙头。

我的客户昨天说,“我想要点击它时突出显示”。没关系,它立即推动一个新的uinavigationcontroller视图......它没有眨眼,所以他很困惑。 Oy公司。

以下是我为解决这个问题所做的工作。我不喜欢它,但这就是我所做的:

我将UIButton子类化(将其命名为FlashingUIButton)。

出于某种原因,我无法在控制模式下突出显示背景图像。它似乎永远不会达到“突出”的状态。不知道为什么会这样。

所以我写了:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self setBackgroundImage:[UIImage imageNamed:@"grey_screen"] forState:UIControlStateNormal];
    [self performSelector:@selector(resetImage) withObject:nil afterDelay:0.2];
    [super touchesBegan:touches withEvent:event];
}

-(void)resetImage
{
    [self setBackgroundImage:nil forState:UIControlStateNormal];
}

这很愉快地将我的grey_screen.png(一个30%不透明的黑色方框)放在按钮上,当它被点击时,用一个快乐的空虚替换它.2秒之后。

这很好,但这意味着我必须浏览所有笔尖并将所有按钮从UIButtons更改为FlashingUIButtons。这不是世界末日,但我真的希望将其作为UIButton类别来解决,并且一举击中所有鸟类。

有什么建议比这更好的方法吗?

3 个答案:

答案 0 :(得分:4)

您可以使用手势识别器拦截触摸事件,然后以编程方式将识别器添加到您的所有uibutton中。例如:

//
//  HighlighterGestureRecognizer.h
//  Copyright 2011 PathwaySP. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface HighlightGestureRecognizer : UIGestureRecognizer {
    id *beganButton;
}

@property(nonatomic, assign) id *beganButton;

@end

和实施:

//
//  HighlightGestureRecognizer.m
//  Copyright 2011 PathwaySP. All rights reserved.
//

#import "HighlightGestureRecognizer.h"


@implementation HighlightGestureRecognizer

@synthesize beganButton;

-(id) init{
    if (self = [super init])
    {
        self.cancelsTouchesInView = NO;
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.beganButton = [[[event allTouches] anyObject] view];
    if ([beganButton isKindOfClass: [UIButton class]]) {
        [beganButton setBackgroundImage:[UIImage imageNamed:@"grey_screen"] forState:UIControlStateNormal];
        [self performSelector:@selector(resetImage) withObject:nil afterDelay:0.2];

    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)reset
{
}

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
    return NO;
}

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
    return NO;
}

- (void)resetImage
{
    [beganButton setBackgroundImage: nil forState:UIControlStateNormal];
}

@end

嗯。我没有测试这段代码,所以如果它不起作用,不要起诉我,只是评论,我们会解决它。我只是快速写了它以供参考。即使它不起作用,逻辑应该仍然是合理的。

编辑:

忘记添加,你将手势识别器添加到按钮的方式就像这样:

HighlighterGestureRecognizer * tapHighlighter = [[HighlighterGestureRecognizer alloc] init];

[myButton addGestureRecognizer:tapHighlighter];
[tapHighlighter release];

所以基本上你要声明它,初始化它,然后添加它。之后,您将要释放它,因为addGestureRecognizer会保留它。

答案 1 :(得分:2)

你的按钮上有adjustsImageWhenHighlighted = YES吗?默认值为YES,但您可能在xib中更改了它。它是属性检查器中的“突出显示的调整图像”复选框:

IB Highlight Button

答案 2 :(得分:0)

在继承UIButton(Swift 2)后,我遇到了同样的问题。当用户触摸UIButton 时,不会调用子类“drawRect”函数(即使在故事板中选中了复选标记“突出显示调整图像”)。这可能是因为它是一个自定义的UIButton。

无论如何,通过覆盖“touchesBegan”和“touchesEnded”事件来处理它很简单。可以做更多的事情来处理按钮的所有状态(如禁用)。但这是代码。

Swift 2:

import Foundation
import UIKit

@IBDesignable

class ppButton: UIButton {
    override func drawRect(rect: CGRect) {
        if self.state != UIControlState.Highlighted  {
            //SKit is another class containing a function to draw the custom button
            SKit.drawPpButton(0, width: rect.width-2, height: rect.height-2)
        } else {
            //SKit is another class containing a function to draw the custom button
            SKit.drawPpButton(0, width: rect.width-20, height: rect.height-20)
        }
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesBegan(touches, withEvent: event)
        self.setNeedsDisplay()
    }
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesEnded(touches, withEvent: event)
        self.setNeedsDisplay()
    }
}