Cocoa Touch - 自定义UIButton形状

3

如何使触摸按钮的区域与提供的图像形状相同?
假设我有一个带三角形图片的自定义按钮,如何确保只处理在该三角形内的触摸。

还是说我要在on touch(触摸)操作函数中进行一些数学计算?


如果您决定拦截触摸事件,那么Apple已经为您完成了所有的数学计算。请参阅UIBezierPath类的containsPoint:方法(http://developer.apple.com/library/ios/documentation/uikit/reference/UIBezierPath_class/Reference/Reference.html#//apple_ref/occ/instm/UIBezierPath/containsPoint:)。 - cobbal
3个回答

3

OBShapedButton 是一个非常棒的项目。

它通过子类化 UIButton 并重写 -pointInside:withEvent: 方法来实现。

@implementation OBShapedButton

// UIView uses this method in hitTest:withEvent: to determine which subview 
// should receive a touch event.
// If pointInside:withEvent: returns YES, then the subview’s hierarchy is 
// traversed; otherwise, its branch
// of the view hierarchy is ignored.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{
    // Return NO if even super returns NO (i.e. if point lies outside our bounds)
    BOOL superResult = [super pointInside:point withEvent:event];
    if (!superResult) {
        return superResult;
    }

    // We can't test the image's alpha channel if the button has no image. 
    // Fall back to super.
    UIImage *buttonImage = [self imageForState:UIControlStateNormal];
    if (buttonImage == nil) {
        return YES;
    }

    CGColorRef pixelColor = [[buttonImage colorAtPixel:point] CGColor];
    CGFloat alpha = CGColorGetAlpha(pixelColor);
    return alpha >= kAlphaVisibleThreshold;
}

@end

[aUIImage colorAtPixel:point]是一个附加的分类方法。


1

Ole's OBShapedButton 项目应该在 SO 上被更多引用。感谢 vikingosegundo,他的 my-programming-examples github 在过去帮助了许多人。你可以看到 Ole 创造的一些内容,以便从自定义 UIButton的透明背景中剥离出操作。我添加了这个组件到我的项目中,并通过以下步骤使其运作。

  1. 下载该项目
  2. 将UIImage+ColorAtPixel.h/m 和OBShapedButton.h/m文件添加到您的项目文件夹中
  3. 确保.m 文件已添加到目标的Build Phases > Compile Sources列表中
  4. 将所有按钮的UIButton类类型更改为 IB 中的 OBShapedButton 类
  5. 确保您的.png文件具有透明背景并将其设置为按钮的“Image”

这个项目将帮助那些有多个重叠的UIButtons,它们具有透明背景,即使它们在不同的UIView中或完全被另一个UIButton覆盖(例如,在IB中无法选择它,除非使用Editor>Arrange>Send to Back/Front)。但是,如果您在UIView中有一个OBShapedButton,其中一部分透明UIView重叠在OBShapedButton上,您将无法在OBShapedButton被覆盖的UIView覆盖部分接收点击或拖动事件,因此请考虑使用这种方式来分层您的UIView。

下载Ole和Viking的项目,加入您的教程集合......赶紧行动吧!


1

核心Cocoa Touch类与UIButton相关的确没有提供此功能。我猜想您需要查看子类化UIButton并拦截点击事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接