自定义UIButton绘图 - 触摸后保持抑制状态

时间:2011-09-20 08:11:07

标签: iphone objective-c uibutton core-graphics

我已经制作了一个自定义的零图像,核心图形基于Ray Wenderlich's Tutorial绘制了UIButton(唯一的修改是针对CoolButton的drawRect:方法,改变了绘图代码),并且它在大多数情况下工作得很好时间。但是,有时当我短时间点击它时,它会处于压低状态并且不会恢复正常。

从这里开始,将它恢复到正常状态的唯一方法是通过长按。只需单击就意味着它会保持低迷状态。

另一件需要注意的事情是,我已经将Touch Up Inside连接到一些长方法链 - 我认为完成它不会超过0.1秒。我甚至在连接到Touch Up Inside的dispatch_async中使用了@selector,因此我认为UI更新不应该有延迟。


我在NSLog中添加drawRect:,每按一次按钮会激活3次,每次按下时按钮所在的UIControlState会有所不同:

  • 对于某些短按,它会突出显示,突出显示,正常
  • 对于更长时间的按下,它是突出显示,正常,正常

然而,对于非常短的按压,它只发射两次,突出显示 - >突出显示。

当长按以使其恢复正常时,它会变为H,N,N。


这让我困惑了一段时间,而且我无法弄清楚为什么短按只会激活drawRect:两次,或者为什么touchesEnded:似乎没有召唤{{1} }}。也许drawRect:没有解雇?

我真的希望有人可以提供帮助。

5 个答案:

答案 0 :(得分:1)

如果确实想要在运行时生成按钮图像,请在加载按钮时生成它们。然后使用

将它们添加到不同的状态
[button setImage:btnImage forState:UIControlStateNormal];

您始终可以使用以下内容将视图转换为图像:http://pastie.org/244916

实际上,我建议您事先制作图像。如果你不想获得photoshop,那就有很多选择。即将到来的pixelmator更新看起来非常温和,而且它的价格非常便宜!

答案 1 :(得分:0)

嗯,好吧,这很容易。 0.15秒延迟工作,0.1不工作。

答案 2 :(得分:0)

正如其他人所说,你可以简单地生成一个图像并将其用作背景(如果图像是静态的)。不需要photoshop,你可以简单地生成你的图像然后拍摄快照,然后剪掉图像(使用Anteprima)并将其保存为png文件:)

但是,由于你说按钮连接到一些很长的方法,这可能就是按钮保持按下的原因:如果你没有在后台调用这些方法,那么按钮将保持按下状态,因为所有任务都已结束。尝试(测试)用一个简单的方法连接按钮(比如说NSLog)并检查它是否保持按下状态。如果没有,我建议你在后台分离你的方法。

答案 3 :(得分:0)

当我自定义drawRect方法时,我也遇到类似的问题,UIButton似乎粘在一个状态。我的预感是,在调用drawRect之前,按钮的状态会多次改变。所以我只添加了一个自定义属性,该属性只能由touchDown和touchUpInside事件期间调用的方法设置。我不得不派遣线程来执行此操作,因为其他操作阻碍了主线程,导致redrawHighlighted方法延迟。

可能有点乱,但这对我有用:

// CustomButton.h
@interface CustomButton : UIButton
@property (atomic) BOOL drawHighlighted;    

// CustomButton.m
@implementation CustomButton
@synthesize drawHighlighted = _drawHighlighted;

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        _drawHighlighted = NO;

        [self addTarget:self action:@selector(redrawHighlighted) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(redrawNormal) forControlEvents:UIControlEventTouchUpInside];
        [self addTarget:self action:@selector(redrawNormal) forControlEvents:UIControlEventTouchDragExit];  
    }
    return self;
}

- (void)drawRect:(CGRect)frame
{
    // draw button here
}

- (void)redrawNormal
{
    [NSThread detachNewThreadSelector:@selector(redrawRectForNormal) toTarget:self withObject:nil];
}

- (void)redrawHighlighted
{
    [NSThread detachNewThreadSelector:@selector(redrawRectForHighlighted) toTarget:self withObject:nil];
}

- (void)redrawRectForNormal
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    _drawHighlighted = NO;  
    [self setNeedsDisplay];

    [pool release];
}

- (void)redrawRectForHighlighted
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    _drawHighlighted = YES; 
    [self setNeedsDisplay];

    [pool release];
}

答案 4 :(得分:0)

我发现另一个便宜但有效的替代方法是创建一个drawRect:它不会进行任何突出显示,只需在用户与按钮交互时更改按钮子类的alpha属性。

例如:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    self.alpha = 0.3f;
    return [super beginTrackingWithTouch:touch withEvent:event];
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    self.alpha = 1.0f;
    [super endTrackingWithTouch:touch withEvent:event];
}

- (void)cancelTrackingWithEvent:(UIEvent *)event
{
    self.alpha = 0.3f;
    [super cancelTrackingWithEvent:event];
}

- (void)drawRect:(CGRect)rect
{
    // Your drawing code here sans highlighting
}