UIBarButtonItems personalizados desde UIButtons con imágenes personalizadas: ¿es posible hacer que los destinos de toque sean más grandes?

Estoy haciendo UIBarButtons de la siguiente manera:

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

Sin embargo, los objectives de toque son pequeños. Más precisamente, son del tamaño de las imágenes personalizadas. (Lo que, una vez más, son pequeños). ¿Hay alguna forma de boost el tamaño de su objective de toque?

(Nota: al modificar la propiedad de marco de los botones UIB solo se estira la image).

Pequeños cambios en su código harán las cosas

Cambios necesarios:

  • Estoy asumiendo que el tamaño de backButtonImage es {28,17} y configurando el marco del button como CGRectMake(0, 0, 48, 37) `
  • quite el backGroundImage y use setImage:
  • establezca la propiedad imageEdgeInsets en UIEdgeInsetsMake(10, 10, 10, 10)

Su código será así:

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

Puede cambiar el valor para el frame y para imageEdgeInsets acuerdo con sus requisitos.
Este código funcionó para mí.

Puede cambiar la propiedad de ancho UIBarButtonItem

 backBarButtonItem.width = x; 

Lamentablemente, no puedes cambiar la altura, porque no hay ninguna propiedad de altura.

Sin embargo, lo que puede hacer es pasar UIBarButtonItem un UIButton con un marco definido usando initWithCustomView

por ejemplo:

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

Si su image se ve estirada, ¡asegúrese de mantener la misma relación de aspecto! O asegúrate de que la image sea exactamente del mismo tamaño.

1) Agregue una categoría a su UIB.
2) Agregar nuevas properties a la categoría
3) Agregue su método para inicializar el button Atrás
4) Anulación -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
5) Subclass 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 

Digamos que el evento táctil no se dispara, necesitamos que la vista sea llamada para llamar al button así que en toolBarItems hacemos algo como:

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

entonces eso es todo. ampliamos el marco sin ampliar el button real.

usted acaba de inicializar su button como: UIButton *btn = [[UIButton alloc]initBackBtnAtPoint:CGPointMake(0,0)];

Espero eso ayude

mmm … para lo que necesitas lograr, eso no es un estiramiento de la image, hay una forma simple:

1) use Gimp o Photoshop y cree una capa transparente debajo de su image, para que coincida con el tamaño que desee.

2) fusionar y crear imágenes de retina y no retina.

3) Actualice su código para que refleje el nuevo tamaño de image.

4) asigne las imágenes y luego ejecute su código.

De esta forma, su image original no se estirará porque sus límites tendrán en count la parte transparente de la misma.

Aparte de eso, probablemente puedas hacer todo esto programáticamente, pero dudo que sea una buena idea, a less que planees sumergirte en UIGraphics por otros motivos.

Cuando llama a initWithCustomView , UIBarButtonItem delega el event handling events a la vista personalizada, que, en su caso, es el UIButton . A su vez, el UIButton está obteniendo los límites de la image, y como image de background, se espera que se extienda para llenar nuevos límites según sea necesario.

En su lugar, establezca las properties imageInsets y imageInsets directamente en UIBarButtonItem. Estas properties se declaran en la class primaria, UIBarItem . También puede configurar sus variantes de paisaje.

Cambia el marco del button a grande y cambia tu línea.

 [backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal]; 

a:

 [backButton setImage:backButtonImage forState:UIControlStateNormal]; 

Solo usa

 [button setImage:backButtonImage forState:UIControlStateNormal]; 

en lugar de

 [backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal]; 

y establece el marco para lo que quieras. La image se centrará y el button recibirá el toque en el cuadro dado.

Algo como esto:

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

Debería poder configurar las inserciones de borde en el button.

así que configure el marco del button para que sea más grande que la image, luego configure las inserciones de borde en el button.

por lo que para expandir su ancho por 10 píxeles en cada lado algo así debería funcionar

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

Aumente los frameworks de UIButton (hasta el tamaño de toque que desee)

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

Si desea ver la image para el button completo, escriba el siguiente método

  [backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal]; 

Si desea ver el tamaño real de la image (No se preocupe, el tamaño de toque es solo el tamaño de su button)

  [backButton setImage:backButtonImage forState:UIControlStateNormal]; 

Y finalmente

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

Espero que te ayude!

Necesita cambiar tres líneas de código y esperar que funcione.

1) Cambie el ancho backButton según su necesidad.

2) Establezca la Image de backButton en lugar de backgroundImage de backButton

 [backButton setImage:backButtonImage forState:UIControlStateNormal]; 

3) También establezca el contenido de contentHorizontalAlignment alignment contentHorizontalAlignment

 backButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;