xcode 非矩形形状的 iPhone 按钮?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1561585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 18:53:52  来源:igfitidea点击:

iPhone button with non-rectangle shape?

iphonexcodebutton

提问by powtac

How can I get a non-rectangular shaped button?

我怎样才能得到一个非矩形形状的按钮?

For example I do have a PNG image with alpha transparency. How can I set the shape of a button to this image without the transparent color.

例如,我确实有一个具有 alpha 透明度的 PNG 图像。如何在没有透明颜色的情况下将按钮的形状设置为此图像。

回答by Form

Like the others say you should have a reasonable surface for registering touch events, but I'm sure you know that and have your reasons so I'll just tell you how I did it:

就像其他人说的,你应该有一个合理的表面来注册触摸事件,但我相信你知道这一点并且有你的理由,所以我会告诉你我是如何做到的:

I needed to do this not so long ago and what I did is what Sixten Otto just suggested. There are some hints in my original question ("UPDATE" section) for getting the alpha value for your image at a certain point:

不久前我需要这样做,而我所做的正是 Sixten Otto 刚刚建议的。我的原始问题(“更新”部分)中有一些提示可用于在某个点获取图像的 alpha 值:

How to create a transparent window with non-rectangular buttons?

如何使用非矩形按钮创建透明窗口?

Edit:I suggest subclassing UIControl in the example below but if you don't need any special behavior on your button apart from the "non-rectangleness" of it then just subclassing a borderless UIButton set up with your PNG will do the job and require less work. You have more control on the control's behavior by subclassing UIControl and doing it the "hard way" though.

编辑:我建议在下面的示例中对 UIControl 进行子类化,但是如果您的按钮除了“非矩形”之外不需要任何特殊行为,那么只需将使用 PNG 设置的无边框 UIButton 子类化即可完成这项工作并需要更少的工作。通过继承 UIControl 并以“困难的方式”进行操作,您可以更好地控制控件的行为。

I would suggest that you subclass UIControland override the touch event methods, then check for alpha under the tapped point and not handle the event if alpha == 0. For drawing you override drawRect:and use the NSImage's drawInRect:fromRec:operation:fraction:method in there to draw your image in the control's frame.

我建议您子类化UIControl并覆盖触摸事件方法,然后检查点击点下的 alpha 并且不处理事件 if alpha == 0。对于绘图,您可以覆盖drawRect:并使用其中的NSImage'sdrawInRect:fromRec:operation:fraction:方法在控件的框架中绘制图像。

First you need to load the image and get a bitmap representation of it:

首先,您需要加载图像并获得它的位图表示:

buttonImage = [NSImage imageNamed:@"myButtonImage"];
buttonImageRep = [[buttonImage representations] objectAtIndex:0];

Then you can draw it to the control's view: (where stateImage is a pointer to the image that must be drawn depending on if the button is pressed or not)

然后您可以将其绘制到控件的视图中:(其中 stateImage 是指向必须根据按钮是否按下而绘制的图像的指针)

- (void)drawRect:(NSRect)aRect {
 [stateImage drawInRect:[self bounds] fromRect:NSMakeRect(0.0,0.0,[buttonImage size].width,[buttonImage size].height)
      operation:NSCompositeSourceOver fraction:1.0];
}

At this point you have drawn your button with your png image. You can override the touch event methods and handle the event if the alpha is not 0:

此时,您已经用 png 图像绘制了按钮。如果 alpha 不是 0,您可以覆盖触摸事件方法并处理事件:

NSColor *colorUnderMouse = [buttonImageRep colorAtX:mouse.x y:mouse.y];
float alpha = [colorUnderMouse alphaComponent];

That's what I did and it works wonderfully. Hope this helps!

这就是我所做的,而且效果非常好。希望这可以帮助!

N.B: My example is for the Mac but it should also work on the iPhone, maybe with some slight modifications.

注意:我的示例适用于 Mac,但它也应该适用于 iPhone,可能需要稍作修改。

回答by Guvante

It sounds like you are looking to have the clickable area of the button exactly match the PNG you are using.

听起来您希望按钮的可点击区域与您使用的 PNG 完全匹配。

If that is what you are looking for, I would firstly say to not do that. The iPhone is pressed using a finger, which generally doesn't have the accuracy to distinguish such a small region.

如果这就是你要找的,我首先会说不要那样做。iPhone 是用手指按压的,手指通常无法准确区分这么小的区域。

However if you are stuck on the idea, then the solution is to not use buttons at all, instead handle the click in a parent frame and manually interpret the X/Y value of the click to determine if it is in some bounding region (In the case of a rounded edge button, would likely consist of oring the result of checking 4 circles and 2 rectangles)

但是,如果您坚持这个想法,那么解决方案是根本不使用按钮,而是处理父框架中的单击并手动解释单击的 X/Y 值以确定它是否在某个边界区域(在圆边按钮的情况,可能包括检查 4 个圆圈和 2 个矩形的结果)

Edit: Realizing part of your original question, I noticed you mentioned you wanted to handle the function automatically based on the Alpha channel. While I would recommend my method of bounding regions, you could in theory accomplish this by sampling the PNG to test the Alpha channel at a value offset by the origin of the button. Potentially even doing this in a normal button's click event.

编辑:意识到您的原始问题的一部分,我注意到您提到您想根据 Alpha 通道自动处理该功能。虽然我会推荐我的边界区域方法,但理论上您可以通过对 PNG 进行采样以在按钮原点偏移的值处测试 Alpha 通道来实现此目的。甚至可能在普通按钮的单击事件中执行此操作。

回答by Daniel

Rectangular buttons are a button type, you can use the custom button type and assign an image to get rid of the rectangular edges of the button...heres a reference to button types http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/doc/c_ref/UIButtonTypeand to UIButton http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html

矩形按钮是一种按钮类型,您可以使用自定义按钮类型并分配一个图像来摆脱按钮的矩形边缘...这里是对按钮类型的引用http://developer.apple.com/iphone/library /documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/doc/c_ref/UIButtonType和 UIButton http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton /UIButton.html

回答by Sixten Otto

As Guvante says, it's really not a good idea to rely on precision touches. Apple, for instance, recommends that controls be at least 44px across.

正如Guvante 所说,依靠精确的触摸确实不是一个好主意。例如,Apple 建议控件的宽度至少为 44 像素

I'd recommend using a UIButtonof type UIButtonTypeCustom, set the button's image to your PNG, and register for touch events (see here for more on event handling). Then, in your action method, you can get the coordinates of the touch out of the event, and test those coordinates against the alpha of your image to see whether you should treat it as a "real" touch or not.

我建议使用 a UIButtonof type UIButtonTypeCustom,将按钮的图像设置为您的 PNG,并注册触摸事件(有关事件处理的更多信息,请参见此处)。然后,在您的操作方法中,您可以从事件中获取触摸的坐标,并根据图像的 alpha 测试这些坐标,以查看是否应将其视为“真实”触摸。

回答by ianh

Another option could be to split your button up into multiple, rectangular parts.

另一种选择是将您的按钮拆分为多个矩形部分。

回答by Andrew Romanov

@Form right about using 'drawRect' to implement custom shape for button.

@Form 正确使用“drawRect”来实现按钮的自定义形状。

But better methodto exam touch inside or not inside button is using of

但是检查触摸内部或不在按钮内部的更好方法是使用

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

You can create your button transparent for touches in some parts.

您可以为某些部分的触摸创建透明的按钮。

If you can't use custom image for button (for example if you draw text on the button) you can use new methodto draw subviews hierarchy into a image:

如果您不能为按钮使用自定义图像(例如,如果您在按钮上绘制文本),您可以使用新方法将子视图层次结构绘制到图像中:

 - (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates;