【问题标题】:Simple way of using irregular shaped buttons使用不规则形状按钮的简单方法
【发布时间】:2011-04-14 21:50:25
【问题描述】:

我终于发布了我的主要应用程序(点击玩 MMO - 看看 ;-)),我现在正在努力扩展它。

为此,我需要一个包含四个单独按钮的圆圈,这些按钮基本上是四分之一。我得出的结论是,圆形图像需要由四个图像构成,每个季度一个,但是由于矩形图像形状的必要性,我最终会出现一些重叠,尽管重叠会是透明的。

让它发挥作用的最佳方法是什么?我需要一些非常简单的东西,我看过这个 http://iphonedevelopment.blogspot.com/2010/03/irregularly-shaped-uibuttons.html

之前但尚未成功使其工作。谁能给点建议?

如果有什么不同,我将部署到 iOS 3.X 框架(当 iPad 推出 4.2 时将是 4.2)

【问题讨论】:

    标签: objective-c ios cocoa-touch button transparent


    【解决方案1】:

    我看不出,为什么需要重叠。
    只需创建 4 个按钮,并为每个按钮分配一张图片。

    评论后编辑

    看到这个great project。一个例子正是你想要做的。

    它通过将像素的 alpha 值合并到覆盖中来工作

    pointInside:withEvent: 和 UIImage 上的一个类别,添加了这个方法

    - (UIColor *)colorAtPixel:(CGPoint)point {
        // Cancel if point is outside image coordinates
        if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point)) {
            return nil;
        }
    
    
        // Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
        // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage
        NSInteger pointX = trunc(point.x);
        NSInteger pointY = trunc(point.y);
        CGImageRef cgImage = self.CGImage;
        NSUInteger width = self.size.width;
        NSUInteger height = self.size.height;
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        int bytesPerPixel = 4;
        int bytesPerRow = bytesPerPixel * 1;
        NSUInteger bitsPerComponent = 8;
        unsigned char pixelData[4] = { 0, 0, 0, 0 };
        CGContextRef context = CGBitmapContextCreate(pixelData, 
                                                     1,
                                                     1,
                                                     bitsPerComponent, 
                                                     bytesPerRow, 
                                                     colorSpace,
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        CGColorSpaceRelease(colorSpace);
        CGContextSetBlendMode(context, kCGBlendModeCopy);
    
        // Draw the pixel we are interested in onto the bitmap context
        CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
        CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
        CGContextRelease(context);
    
        // Convert color values [0..255] to floats [0.0..1.0]
        CGFloat red   = (CGFloat)pixelData[0] / 255.0f;
        CGFloat green = (CGFloat)pixelData[1] / 255.0f;
        CGFloat blue  = (CGFloat)pixelData[2] / 255.0f;
        CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
        return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
    }
    

    【讨论】:

    • 如果这么简单。我需要的是 45 度旋转,所以不幸的是它不是那么简单。
    • 我必须承认我错过了您的编辑 - 我不得不改变我的方法,但要使用一张图像并尝试以某种方式在顶部(混乱但仍然)覆盖触摸事件,因为我的图像不太网格化正确的。也就是说,我稍后会测试答案,如果正确,则将其标记为正确,以便问题有答案。
    • 我忘了提一下,通过这个解决方案,您可以保留 - 作为 OBShapedButton 从 UIButton 继承 - UIButton 的全部功能,尤其是在 InterfaceBuilder 中
    【解决方案2】:

    跳过按钮,只需对包含圆圈的视图中的触摸做出响应。

    为您要捕获触摸的每个区域创建一个 CGPath,当您的 UIview 接收到触摸时,检查路径内的成员资格。

    [编辑答案以显示骨架实现细节——TomH]

    这是我解决问题的方法:(我还没有测试过这段代码,语法可能不太正确,但这是大体思路)

    1) 使用 PS 或您喜欢的图像创建应用程序,创建四分之一圆的 png。将其添加到您的 XCode 项目中。

    2) 将 UIView 添加到 UI。将 UIView 的图层内容设置为 png。

    self.myView = [[UIView alloc] initWithRect:CGRectMake(10.0, 10.0, 100.0, 100,0)];
    [myView.layer setContents:(id)[UIImage loadImageNamed:@"my.png"]];
    

    3) 创建描述 UIView 中您感兴趣的区域的 CGPath。

    self.quadrantOnePath = CGPathCreateMutable();
    CGPathMoveToPoint(self.quadrantOnePath, NULL, 50.0, 50.0);
    CGPathAddLineToPoint(self.quadrantOnePath, NULL, 100.0, 50.0);
    CGPathAddArc(self.quadrantOnePath, NULL, 50.0, 50.0, 50.0, 0.0, M_PI2, 1);
    CGPathCloseSubpath(self.quadrantOnePath);
    
    // create paths for the other 3 circle quadrants too!
    

    4) 添加 UIGestureRecognizer 并监听/观察视图中的点击

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [tapRecognizer setNumberOfTapsRequired:2]; // default is 1
    

    5) 当 tapRecognizer 调用它的目标选择器时

    - (void)handleGesture:(UIGestureRecognizer *) recognizer {
    
      CGPoint touchPoint = [recognizer locationOfTouch:0 inView:self.myView];
      bool processTouch = CGPathContainsPoint(self.quadrantOnePath, NULL, touchPoint, true);
    
      if(processTouch) {
         // call your method to process the touch
      }
    }
    

    不要忘记在适当的时候释放所有东西——使用 CGPathRelease 释放路径。

    另一个想法:如果您用来表示圆形象限的图形只是一种填充颜色(即没有花哨的图形、图层效果等),您还可以使用您在 UIView 的 drawRect 方法中创建的路径来也画出象限。这将解决上述方法的缺点之一:图形和用于检查触摸的路径之间没有紧密集成。也就是说,如果您将图形换成不同的东西,更改图形的大小等,用于检查触摸的路径将不同步。可能是一段需要大量维护的代码。

    【讨论】:

    • 这将是理想且最不混乱的解决方案 - 您能详细说明如何做到这一点吗?
    • 编辑了上面的答案以说明这样做的一种方法。
    【解决方案3】:

    这是一个很棒的项目,可以轻松解决不规则形状按钮的问题: http://christinemorris.com/2011/06/ios-irregular-shaped-buttons/

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    相关资源
    最近更新 更多