ios 来自带有自定义图像的 UIButtons 的自定义 UIBarButtonItems - 是否可以使点击目标更大?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16451639/
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
Custom UIBarButtonItems from UIButtons with custom images - is it possible to make the tap targets larger?
提问by Doug Smith
I'm making UIBarButtons as follows:
我正在制作 UIBarButtons 如下:
// Create "back" UIBarButtonItem
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 28, 17);
[backButton addTarget:self action:@selector(backButtonTapped) forControlEvents:UIControlEventTouchUpInside];
backButton.showsTouchWhenHighlighted = YES;
UIImage *backButtonImage = [UIImage imageNamed:@"back-button.png"];
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
[toolBarItems addObject:backBarButtonItem];
However, the tap targets are tiny. More precisely, they're the size of the custom images. (Which again, are tiny.) Is there any way to increase the size of their tap target?
但是,点击目标很小。更准确地说,它们是自定义图像的大小。(同样,很小。)有没有办法增加他们的点击目标的大小?
(Note: altering the frame property of the UIButtons just stretches the image.)
(注意:改变 UIButtons 的 frame 属性只会拉伸图像。)
回答by Prasad Devadiga
Small changes to your code will do the stuff
对您的代码进行小的更改即可
Changes needed :
需要改变:
- I am assuming that the size of
backButtonImage
is{28,17}
and setting the button frame asCGRectMake(0, 0, 48, 37)
` - remove the
backGroundImage
and usesetImage:
- set the property
imageEdgeInsets
toUIEdgeInsetsMake(10, 10, 10, 10)
- 我假设大小
backButtonImage
是{28,17}
并将按钮框架设置为CGRectMake(0, 0, 48, 37)
` - 删除
backGroundImage
并使用setImage:
- 将属性设置
imageEdgeInsets
为UIEdgeInsetsMake(10, 10, 10, 10)
Your code will become like this:
你的代码会变成这样:
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 48, 37);
[backButton addTarget:self action:@selector(backButtonTapped) forControlEvents:UIControlEventTouchUpInside];
backButton.showsTouchWhenHighlighted = YES;
UIImage *backButtonImage = [UIImage imageNamed:@"back-button.png"];
[backButton setImage:backButtonImage forState:UIControlStateNormal];
backButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
[toolBarItems addObject:backBarButtonItem];
You can change the value for the frame
and the imageEdgeInsets
as per your requirements.
This code worked for me.
您可以更改值frame
和imageEdgeInsets
按您的要求。
这段代码对我有用。
回答by VGruenhagen
You can change the UIBarButtonItem
's width property
您可以更改UIBarButtonItem
的宽度属性
backBarButtonItem.width = x;
Unfortunately you can't change the height is way, because there is no height property.
不幸的是,您无法更改高度,因为没有高度属性。
What you can do however is pass UIBarButtonItem
an UIButton
with a defined frame using initWithCustomView
但是什么你能做的就是通过UIBarButtonItem
一个UIButton
使用定义的帧initWithCustomView
for example:
例如:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backButtonImage = [UIImage imageNamed:@"back-button.png"];
[button setBackgroundImage:backButtonImage forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, width, height);
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
If your image looks stretched, make sure you maintain the same aspect ratio! Or make sure the image is exactly the same size.
如果您的图像看起来被拉伸,请确保保持相同的纵横比!或者确保图像大小完全相同。
回答by Joshua
1) Add a category to your UIButton
2) Add new properties to the category
3) Add your method to initialise the back button
4) Override -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
5) Subclass toolBarItems
1) 向您的 UIButton 添加类别
2) 向类别添加新属性
3) 添加您的方法以初始化后退按钮
4) 覆盖-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
5) 子类 toolBarItems
@implementation UIButton (yourButtonCategory)
@dynamic shouldHitTest; // boolean
@dynamic hitTestRect; // enlarge rect of the button
@dynamic buttonPressedInterval; // interval of press, sometimes its being called twice
-(id)initBackBtnAtPoint:(CGPoint)_point{
// we only need the origin of the button since the size and width are fixed so the image won't be stretched
self = [self initWithFrame:CGRectMake(_point.x, _point.y, 28, 17)];
[self setBackgroundImage:[UIImage imageNamed:@"back-button.png"]forState:UIControlStateNormal];
self.shouldHitTest = CGRectMake(self.frame.origin.x - 25, self.frame.origin.y-10, self.frame.size.width+25, self.frame.size.height+25); // this will be the enlarge frame of the button
self.shouldHitTest = YES;
return self;
}
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
BOOL shouldReturn = [super pointInside:point withEvent:event];
NSSet *touches = [event allTouches];
BOOL shouldSendTouches = NO;
for (UITouch *touch in touches) {
switch (touch.phase) {
case UITouchPhaseBegan:
shouldSendTouches = YES;
break;
default:
shouldSendTouches = NO;
break;
}
}
if(self.shouldHitTest){
double elapse = CFAbsoluteTimeGetCurrent();
CGFloat totalElapse = elapse - self.buttonPressedInterval;
if (totalElapse < .32) {
return NO;
// not the event we were interested in
} else {
// use this call
if(CGRectContainsPoint(self.hitTestRect, point)){
if(shouldSendTouches){
self.buttonPressedInterval = CFAbsoluteTimeGetCurrent();
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
return NO;
}
}
}
return shouldReturn;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint touch_point = [touch locationInView:self];
[self pointInside:touch_point withEvent:event];
}
@end
Lets say the touch event doesn't trigger we need the view its in to call the button so in toolBarItems we do something like:
假设触摸事件不会触发,我们需要它的视图来调用按钮,因此在 toolBarItems 中,我们执行以下操作:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
for(id subs in self.subviews){
if([subs isKindOfClass:[UIButton class]]){
[subs touchesBegan:touches withEvent:event];
}
}
}
then thats it. we enlarge the frame without enlarging the actual button.
那么就是这样。我们放大框架而不放大实际按钮。
you just initial your button like: UIButton *btn = [[UIButton alloc]initBackBtnAtPoint:CGPointMake(0,0)];
您只需初始化您的按钮,例如: UIButton *btn = [[UIButton alloc]initBackBtnAtPoint:CGPointMake(0,0)];
Hope it helps
希望能帮助到你
回答by Alexander Merchi
Change button frame to large and change your line
将按钮框架更改为大并更改您的行
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
to:
到:
[backButton setImage:backButtonImage forState:UIControlStateNormal];
回答by Lukas Kukacka
Just use
只需使用
[button setImage:backButtonImage forState:UIControlStateNormal];
instead of
代替
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
and set the frame to whatever you like. The image will then be centered and the button will receive the touch in the given frame.
并将框架设置为您喜欢的任何内容。然后图像将居中,按钮将在给定帧中接收触摸。
Something like this:
像这样的东西:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(50, 50, 50, 50);
[button setImage:backButtonImage forState:UIControlStateNormal];
回答by Steven McGrath
When you call initWithCustomView
, the UIBarButtonItem
delegates event handling to the custom view, which, in your case, is the UIButton
. In turn, the UIButton
is getting its bounds from the image, and as a background image, it is expected to stretch to fill new bounds as needed.
当您调用 时initWithCustomView
,UIBarButtonItem
将事件处理委托给自定义视图,在您的情况下,它是UIButton
. 反过来,UIButton
它从图像中获取边界,并且作为背景图像,预计会根据需要拉伸以填充新边界。
Instead, set the image
and imageInsets
properties directly on the UIBarButtonItem. These properties are declared on the parent class, UIBarItem
. You may also wish to set their landscape variants.
相反,直接在 UIBarButtonItem 上设置image
和imageInsets
属性。这些属性在父类上声明,UIBarItem
。您可能还希望设置它们的横向变体。
回答by Alex
mmm... for what you need to achieve - that is no image stretch - there's a simple way:
嗯...对于您需要实现的目标 - 这不是图像拉伸 - 有一个简单的方法:
1) use Gimp or photoshop and create a transparent layer below your image, so that it matches the size you want.
1) 使用 Gimp 或 photoshop 并在图像下方创建一个透明层,使其与您想要的大小相匹配。
2) merge down and create retina and non-retina images.
2)合并并创建视网膜和非视网膜图像。
3) update your code so that it reflect the new image size.
3) 更新您的代码,使其反映新的图像大小。
4) assign the images and then run your code.
4)分配图像,然后运行您的代码。
This way your original image won't be stretched because it's boundaries will take into account the transparent portion of it.
这样你的原始图像就不会被拉伸,因为它的边界会考虑到它的透明部分。
Other than that, you can probably do this all programatically, but I doubt this is a good idea, unless you planned to dive into UIGraphics for other reasons.
除此之外,您可能可以通过编程方式完成这一切,但我怀疑这是一个好主意,除非您出于其他原因计划深入研究 UIGraphics。
回答by korat prashant
You need to change three line of code and hope its working.
您需要更改三行代码并希望其正常工作。
1)Change the backButton width as per your need.
1) 根据需要更改 backButton 宽度。
2)Set backButton's Image
instead of backButton's BackgroundImage
2) 设置 backButtonImage
而不是 backButtonBackgroundImage
[backButton setImage:backButtonImage forState:UIControlStateNormal];
3)Also set backButton's contentHorizontalAlignment
3)同时设置backButton的 contentHorizontalAlignment
backButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
回答by andrew lattis
you should be able to just set the edge insets on the button.
您应该能够在按钮上设置边缘插入。
so set the frame of the button to be larger than the image, then set the edge insets on the button.
因此将按钮的框架设置为大于图像,然后在按钮上设置边缘插入。
so to expand your width by by 10 pixels on each side something like this should work
所以要在每一侧将宽度扩大 10 个像素,这样的事情应该可行
backButton.frame = CGRectMake(0,0,28,37);
backButton.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);
回答by Ganee....
Increase the UIButton frames(up to the tap size you want)
增加 UIButton 框架(达到你想要的水龙头大小)
button.frame = CGRectMake(0, 0, 56, 20);
If you want to see the image for complete button please write following method
如果您想查看完整按钮的图像,请编写以下方法
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
If you want to see the image actual size (Dont worry tap size is your button size only)
如果您想查看图像的实际大小(不要担心水龙头大小只是您的按钮大小)
[backButton setImage:backButtonImage forState:UIControlStateNormal];
And finally
最后
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
Hope it helps you!
希望对你有帮助!