【问题标题】:UIButton and UIControlEventState issueUIButton 和 UIControlEventState 问题
【发布时间】:2010-04-04 21:10:33
【问题描述】:

我的 iPhone 应用程序中有一个非常具体的“错误”。我正在为按钮的突出显示和正常状态设置两个图像。当您“按下”然后以缓慢的速度“润色”时,它会按预期工作,但如果您快速单击/点击它,状态之间会出现明显的闪烁。这是一个已知的错误还是我错误地设置了状态?

这是创建按钮的代码:

UIImage *normalImage = [[UIImage imageNamed:@"btn-small.png"] stretchableImageWithLeftCapWidth:10.0f topCapHeight:0.0f];
UIImage *highlightedImage = [[UIImage imageNamed:@"btn-small-down.png"] stretchableImageWithLeftCapWidth:10.0f topCapHeight:0.0f];

[self setBackgroundColor:[UIColor clearColor]];

[self setBackgroundImage:normalImage forState:UIControlStateNormal];
[self setBackgroundImage:highlightedImage forState:UIControlStateDisabled];
[self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];

[self setAdjustsImageWhenDisabled:FALSE];
[self setAdjustsImageWhenHighlighted:FALSE];

当一个按钮被点击时,它只是禁用自身并启用另一个按钮:

- (IBAction)aboutButtonTouched:(id)sender
{
    aboutButton.enabled = FALSE;
    rulesButton.enabled = TRUE;
}

- (IBAction)rulesButtonTouched:(id)sender
{
    rulesButton.enabled = FALSE;
    aboutButton.enabled = TRUE;
}

对这种快速点击闪烁有什么想法吗?

【问题讨论】:

    标签: iphone objective-c button


    【解决方案1】:

    好的,我解决了这个问题。对我想做的事情进行了一些逆向工程,但我想我会发布我所做的以防万一它对其他人有所帮助。

    我做的第一件事是修改 aboutButtonTouched 方法来记录按钮的状态属性,它是一个位掩码 NSUInteger:

    - (IBAction)aboutButtonTouched:(id)sender
    {
        rulesButton.enabled = TRUE;
        [sender setEnabled:FALSE];    
    
        NSLog(@"%d", [sender state]);
    }
    

    此时按钮通过setEnabled禁用,日志报告状态为“3”。查看 UIControlState 的位掩码类型:

    enum {
       UIControlStateNormal               = 0,            // 0
       UIControlStateHighlighted          = 1 << 0,       // 1
       UIControlStateDisabled             = 1 << 1,       // 2
       UIControlStateSelected             = 1 << 2,       // 4
       UIControlStateApplication          = 0x00FF0000,
       UIControlStateReserved             = 0xFF000000
    };
    

    (添加注释,因为我永远记不住按位)。我们可以看到,要获得“3”(0011),我们应该使用UIControlStateHighlighted | UIControlStateDisabled(0001|0010 或 1|2),这是我在原始按钮定义中没有的状态。这里的关键是状态在被禁用之前有一个短暂的时间(“当在跟踪期间进入和退出触摸以及进行触摸时,控件进入此状态” - 来自文档)。所以它不闪烁的按钮的最终状态设置是:

    [self setBackgroundImage:normalImage forState:UIControlStateNormal];
    [self setBackgroundImage:highlightedImage forState:UIControlStateDisabled];
    [self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
    [self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted|UIControlStateDisabled];
    

    【讨论】:

    • 我不知道为什么;但在我对 iOS5 的测试中,它不是“3”而是“5”。这是“UIControlStateSelected|UIControlStateHighlighted”
    • @HansPinckaers 如果他们将新项目添加到位掩码中,则值可能已更改。
    • 好吧,我只是继承了 UIButton 并添加了一个将状态 1 设置为 5 的方法。不再闪烁 :)
    【解决方案2】:

    需要注意的是,虽然没有记录,但所有包含 UIControlStateHighlighted|UIControlStateDisabled 的状态组合都是无效的:这些与没有 UIControlStateDisabled 的状态组合相同。

    简而言之:

    (UIControlStateHighlighted | UIControlStateDisabled) == UIControlStateHighlighted

    (UIControlStateSelected | UIControlStateHighlighted | UIControlStateDisabled) == (UIControlStateSelected | UIControlStateHighlighted)

    我发现困难的方法是:为 Highlighted+Disabled 状态设置一些属性,这会覆盖我对 Highlighted 状态的设置。花了半天的时间追查为什么按钮没有正确突出显示的问题......

    【讨论】:

      【解决方案3】:

      也许您应该颠倒更改按钮的顺序

      - (IBAction)aboutButtonTouched:(id)sender
      {
          rulesButton.enabled = TRUE;
          aboutButton.enabled = FALSE;
      }
      

      当您先隐藏一个按钮然后显示另一个按钮时,可能会有一点间隙,这会产生闪烁。我认为最好先显示另一个按钮。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-21
        • 1970-01-01
        • 2011-06-22
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多