来自UIButtons的自定义UIBarButtonItems带有自定义图像 - 是否可以使点击目标更大?

时间:2013-05-08 23:02:14

标签: ios objective-c uibutton uibarbuttonitem uitoolbar

我按如下方式制作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];

然而,水龙头目标很小。更准确地说,它们是自定义图像的大小。 (再次,这很小。)有没有办法增加他们的水龙头目标的大小?

(注意:改变UIButtons的框架属性只会拉伸图像。)

10 个答案:

答案 0 :(得分:26)

对代码进行细微更改将会完成这些工作

需要进行更改:

  • 我假设backButtonImage的大小为{28,17},并将按钮框设为CGRectMake(0, 0, 48, 37)`
  • 删除backGroundImage并使用setImage:
  • 将属性imageEdgeInsets设置为UIEdgeInsetsMake(10, 10, 10, 10)

您的代码将变为:

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];

您可以根据自己的要求更改frameimageEdgeInsets的值 这段代码对我有用。

答案 1 :(得分:5)

您可以更改UIBarButtonItem的宽度属性

backBarButtonItem.width = x;

不幸的是,你不能改变高度,因为没有高度属性。

然而,您可以使用UIBarButtonItem

通过UIButton initWithCustomView 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]; 定义的框架

例如:

{{1}}

如果图像看起来很拉伸,请确保保持相同的宽高比!或者确保图像大小完全相同。

答案 2 :(得分:3)

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

让我们说触摸事件不会触发我们需要视图来调用按钮,所以在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];
        }
    }


}
那就好了。我们放大框架而不放大实际按钮。

您只需将按钮初始化为:UIButton *btn = [[UIButton alloc]initBackBtnAtPoint:CGPointMake(0,0)];

希望有所帮助

答案 3 :(得分:1)

当您致电initWithCustomView时,UIBarButtonItem会将事件处理委托给自定义视图,在您的情况下,该视图是UIButton。反过来,UIButton正在从图像中获取其边界,并且作为背景图像,预期会根据需要进行拉伸以填充新边界。

而是直接在UIBarButtonItem上设置imageimageInsets属性。这些属性在父类UIBarItem上声明。您可能还希望设置其景观变体。

答案 4 :(得分:1)

mmm ...因为你需要实现的目标 - 这不是图像延伸 - 这是一个简单的方法:

1)使用Gimp或photoshop,在图片下方创建一个透明图层,使其与您想要的尺寸相匹配。

2)合并并创建视网膜和非视网膜图像。

3)更新您的代码,使其反映新的图片大小。

4)分配图像,然后运行代码。

这样您的原始图像就不会被拉伸,因为它的边界会考虑它的透明部分。

除此之外,您可以以编程方式执行此操作,但我怀疑这是一个好主意,除非您计划因其他原因潜入UIGraphics。

答案 5 :(得分:1)

将按钮框更改为大并更改行

[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];

为:

[backButton setImage:backButtonImage forState:UIControlStateNormal];

答案 6 :(得分:1)

您需要更改三行代码并希望其正常工作。

1)根据需要更改backButton宽度。

2)设置backButton的Image而不是backButton的BackgroundImage

[backButton setImage:backButtonImage forState:UIControlStateNormal];

3)同时设置backButton的contentHorizontalAlignment

backButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;

答案 7 :(得分:1)

只需使用

[button setImage:backButtonImage forState:UIControlStateNormal];

而不是

[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];

并将框架设置为您喜欢的任何内容。然后图像将居中,按钮将在给定的帧中接收触摸。

这样的事情:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(50, 50, 50, 50);
[button setImage:backButtonImage forState:UIControlStateNormal];

答案 8 :(得分:0)

您应该只需在按钮上设置边缘插入。

因此将按钮的框架设置为大于图像,然后在按钮上设置边缘插入。

所以要将每边的宽度扩大10个像这样的东西

backButton.frame = CGRectMake(0,0,28,37);
backButton.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);

答案 9 :(得分:0)

增加UIButton帧(最多为您想要的抽头大小)

      button.frame = CGRectMake(0, 0, 56, 20);

如果您想查看完整按钮的图像,请编写以下方法

      [backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];

如果你想看到图像的实际尺寸(不要担心拍子尺寸只是你的按钮尺寸)

      [backButton setImage:backButtonImage forState:UIControlStateNormal];

最后

      UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

希望它可以帮到你!