16

我正在制作 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 的 frame 属性只会拉伸图像。)

4

10 回答 10

26

对你的代码做一些小的改动就可以了

需要更改:

  • 我假设 is 的大小backButtonImage并将{28,17}按钮框架设置为CGRectMake(0, 0, 48, 37)`
  • 删除backGroundImage并使用setImage:
  • 将属性设置imageEdgeInsetsUIEdgeInsetsMake(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];

您可以根据需要更改 theframe和 the的值imageEdgeInsets
这段代码对我有用。

于 2013-05-17T07:17:16.377 回答
5

您可以更改UIBarButtonItem的宽度属性

backBarButtonItem.width = x;

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

但是,您可以做的是使用定义的框架传递UIBarButtonItem一个UIButtoninitWithCustomView

例如:

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

如果您的图像看起来被拉伸,请确保保持相同的纵横比!或者确保图像大小完全相同。

于 2013-05-08T23:08:56.317 回答
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)];

希望能帮助到你

于 2013-05-16T05:41:03.080 回答
1

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

相反,直接在 UIBarButtonItem 上设置image和属性。imageInsets这些属性在父类上声明,UIBarItem. 您可能还希望设置他们的景观变体。

于 2013-05-11T05:40:06.280 回答
1

嗯...对于您需要实现的目标-没有图像拉伸-有一种简单的方法:

1) 使用 Gimp 或 Photoshop 并在图像下方创建一个透明层,使其与您想要的大小相匹配。

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

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

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

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

除此之外,您可能可以通过编程方式完成这一切,但我怀疑这是一个好主意,除非您计划出于其他原因深入研究 UIGraphics。

于 2013-05-11T14:06:32.500 回答
1

将按钮框架更改为大并更改您的行

[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];

到:

[backButton setImage:backButtonImage forState:UIControlStateNormal];
于 2013-05-16T10:47:18.090 回答
1

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

1)根据您的需要更改后退按钮的宽度。

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

[backButton setImage:backButtonImage forState:UIControlStateNormal];

3)还设置了backButton的contentHorizontalAlignment

backButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
于 2013-05-17T06:30:05.923 回答
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];
于 2013-05-17T14:17:41.753 回答
0

您应该能够在按钮上设置边缘插图。

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

所以要在每边将宽度扩大 10 个像素,这样的东西应该可以工作

backButton.frame = CGRectMake(0,0,28,37);
backButton.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);
于 2013-05-08T23:08:39.240 回答
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];

希望对你有帮助!

于 2013-05-16T14:06:20.460 回答