52 votes

Comment puis-je prévenir une touche de l'image d'arrière-plan à partir d'étirement?

Je suis l'allocation d'une UIButtonTypeCustom UIButton à une UIView avec une image de fond qui est plus petit que le bouton de l'image. Pourquoi l'image est plus petite est parce que je suis en train d'ajouter plus d'une "zone cible" pour la UIButton. Cependant, l'image est redimensionnée à la taille totale de l'image, plutôt que d'être simplement la taille de votre image.

J'ai essayé le réglage de la UIButton et UIButton de l'imageView contentMode à la propriété "UIViewContentModeScaleAspectFit", mais pas de chance, l'image est toujours tendue.

Est-il un moyen de faire ce que je suis en train de le faire par programmation?

Merci à l'avance!

125voto

Michael G. Emmons Points 16681

Beaucoup de gens font la même erreur que vous faites en ce qui concerne les images de bouton, puis sauter à travers des cerceaux en essayant de rendre le bouton de se comporter comme ils attendent. Nous allons éclaircir ce point une fois pour toutes:

Un UIButton il y a deux types d'images qu'il peut afficher -- une image de premier plan et un arrière-plan de l'image. L'image d'arrière-plan pour un bouton est prévu pour remplacer le bouton de la texture d'arrière-plan. En tant que tel, il est logique qu'elle s'étend à remplir la totalité de l'arrière-plan. Cependant, la touche de l'image au premier plan est prévu pour être une icône qui peut ou peut ne pas s'afficher aux côtés de texte; il ne sera pas extensible. Il peut rétrécir si le cadre est plus petit que l'image, mais il ne sera pas extensible. Vous pouvez même définir l'alignement de l'image de premier plan à l'aide de l'alignement du Contrôle des propriétés dans Interface Builder.

Un bouton de premier et d'arrière-plan de l'image peut être définie dans le code comme ceci:

// stretchy
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal];  

// not stretchy
[self setImage:forgroundImage forState:UIControlStateNormal]; 

9voto

Zoltán Matók Points 1518

Vous n'avez pas accès à l'arrière-plan imageView, mais il est entièrement fonctionnel solution de contournement:

Au lieu d'appeler -setBackgroundImage:forState:, créez un nouveau UIImageView et ajoutez-la à la sous-vue de la touche.

UIImageView *bgImageView = [[UIImageView alloc] initWithImage:img];
bgImageView.contentMode = UIViewContentModeScaleAspectFit;
[bgImageView setFrame:CGRectMake(0, 0, videoButton.frame.size.width, videoButton.frame.size.height)];
bgImageView.tag = 99;
[yourButton addSubview:bgImageView];
[yourButton bringSubviewToFront:yourButton.imageView];
  1. Créer l'imageview
  2. Définir le mode de contenu et le cadre
  3. J'ai aussi mis une reconnaissables de la marque, de sorte que lorsque l'écran pivote je peux facilement trouver mon custom imageView dans le bouton des sous-vues et de réinitialiser son cadre
  4. Ajoutez-la à la sous-vue sur le bouton
  5. Apporter la frontale imageView du bouton à l'avant de sorte que notre coutume imageView ne se chevauchent pas, il

Lorsque le bouton doit tourner viens de trouver sur le imageView de son étiquette et de réinitialiser son cadre:

UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99];
[bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)];

0voto

Epsilon3 Points 50

Une autre considération est la Référence de la contrainte. Si vos boutons ont cette contrainte (figurée par une ligne horizontale ou verticale par le biais de multiples contrôles sur votre mise en page), il sera la cause de vos images pour étirer sans l'étirer, le sous-jacent bouton de contrôle. Si votre bouton est par ailleurs correctement contrainte (avant/après et haut/bas d'espaces, etc...) retrait de la ligne de Base de la contrainte ne devrait avoir aucune incidence sur la mise en page, tout en permettant à l'image de premier plan à l'échelle correctement à la sous-jacentes bouton de forme.

0voto

LEO Points 526

Answerbot répond à la question avec ce qui est juste et bon de le faire. Ne pas lutter contre le système d'exploitation et utiliser les choses que l'intention est toujours de bons conseils. Cependant, parfois, vous avez besoin de briser les règles.

J'ai été en mesure de masquer l'agrandissement de l'image de fond (pas l'empêcher) par la superposition avec un noir CAlayer alors la superposition de nouveau correctement l'image redimensionnée CAlayer. Cela a été fait par la création d'une sous-classe de UIButton et d'écraser le setHighlighted méthode.

BESOIN DE CODE?

- (void)setHighlighted:(BOOL)highlighted
{
super.highlighted = highlighted;

//
//Whenever an image needs to be highlighted, create a dimmed new image that is correctly       sized. Below it is a englarged stretched image.
//
if (highlighted != _previousHighlightedSate)
{
    _previousHighlightedSate = highlighted;

    if (highlighted)
    {
        //Create a black layer so image can dim
        _blackLayer = [CALayer layer];
        _blackLayer.bounds = self.bounds;
        CGRect rect = _blackLayer.bounds;
        rect.size.width = rect.size.width*2;
        rect.size.height = rect.size.height*2;
        _blackLayer.bounds = rect;
        _blackLayer.backgroundColor = [[UIColor blackColor] CGColor];

        //create image layer
        _nonStretchImageLayer = [CALayer layer];
        _nonStretchImageLayer.backgroundColor = [UIColor blackColor].CGColor;
        _nonStretchImageLayer.bounds = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
        _nonStretchImageLayer.frame = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
        _nonStretchImageLayer.contentsGravity = kCAGravityResizeAspect;//default is to resize
        _nonStretchImageLayer.contents = (id)self.imageView.image.CGImage;
        _nonStretchImageLayer.opacity = 0.5;

        //add layers to image view
        [self.imageView.layer addSublayer:_blackLayer];
        [self.imageView.layer addSublayer:_nonStretchImageLayer];
    }
    else
    {
        //remove from image view
        [_blackLayer removeFromSuperlayer];
        [_nonStretchImageLayer removeFromSuperlayer];

        //nil them out.
        _blackLayer = nil;
        _nonStretchImageLayer = nil;
    }
}  

L'Inspiration pour ce travail autour de est venu à partir d' ici

0voto

MacMark Points 1663

Je suppose que la solution la plus simple est d'utiliser UIImage de resizableImageWithCapInsets méthode. Utilisation UIEdgeInsetsMake pour configurer les espaces libres.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X