iPhone UIButton – posición de la imagen

Tengo un UIButton con el texto «Explorar la app» y UIImage (>)
En Interface Builder parece:

[ (>) Explore the app ]

Pero necesito colocar este UIImage DESPUÉS del texto:

[ Explore the app (>) ]

¿Cómo puedo mover el UIImage a la derecha?

14 Kommentare

  1. 159

    Mi solución a esto es muy simple

    [button sizeToFit];
    button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
    button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width);
    • Esto funciona muy bien! Es difícil entender el borde del recuadro concepto. Alguna idea de por qué necesitamos tanto a la izquierda como a la derecha del borde del recuadro? Teóricamente, si muevo el título a la izquierda y a la imagen a la derecha, que sería suficiente. ¿Por qué necesito para establecer tanto la izquierda y la derecha?
    • LA MEJOR SOLUCIÓN QUE HE ENCONTRADO
    • Esta respuesta funciona a la perfección. El aceptó respuesta es correcta, y los puntos para la correcta API de google docs, pero este es el copiar y pegar solución para hacer lo que el OP solicitado.
    • Se vuelve un poco complicado cuando usted comience a cambiar el texto del botón. La subclase de solución funcionado mejor para mí en este caso.
    • Gracias por mostrarme que usted tiene que aplicar anchos iguales a los lados izquierdo y derecho, no estoy 100% entender cómo funciona (porque a veces se afecta el tamaño, así como el origen), pero he sido capaz de resolver problemas similares utilizando este método.
  2. 123

    Sobre iOS 9 en adelante, parece que una manera sencilla de lograr esto es a la fuerza semántica de la vista.

    iPhone UIButton - posición de la imagen

    O mediante programación, utilizando:

    button.semanticContentAttribute = .ForceRightToLeft
    • Tanto como me gustó su respuesta (+1), odio decirlo, puede que no sea la «correcta» forma de hacer esto, pero es uno de los más fáciles.
    • estás en lo correcto. He cambiado la palabra «simple», parece más coherente.
    • ¿Por qué esta no sea la «correcta» forma de hacer?
    • En mi humilde opinión, la forma correcta sería la de crear una subclase de la UIButton y reemplazar layoutSubviews y el respeto semanticContentAttribute en nuestro diseño de la lógica, en lugar de cambiar semanticContentAttribute sí mismo. (cambio de enfoque semántico, no va a funcionar bien con la internacionalización)
    • es totalmente correcto. No importa que esta respuesta de las puntuaciones de la mayoría de los puntos no es correcto – Se puede romper la UX de derecha a izquierda de la interfaz.
  3. 85

    Conjunto de la imageEdgeInset y titleEdgeInset a mover alrededor de los componentes dentro de la imagen. También podría crear un botón mediante los gráficos que es de tamaño completo, y usar eso como la imagen de fondo para el botón (a continuación, utilizar titleEdgeInsets para mover el título).

    • Es mucho menos código, simplemente, establecer los márgenes que la ejecución de una subclase. Este es el punto entero de los recuadros. La manipulación de los marcos para los sub puntos de vista (que no ha creado) se siente más como un hack.
    • de verdad? Es mucho menos trabajo (y menos de un hack) para ajustar los márgenes cada vez que realice un cambio menor en el tamaño de la imagen o de la longitud del título?
  4. 54

    Raymond W respuesta es mejor aquí. Subclase UIButton con la costumbre de layoutSubviews. Muy simple de hacer, he aquí una layoutSubviews aplicación que trabajó para mí:

    - (void)layoutSubviews
    {
        //Allow default layout, then adjust image and label positions
        [super layoutSubviews];
    
        UIImageView *imageView = [self imageView];
        UILabel *label = [self titleLabel];
    
        CGRect imageFrame = imageView.frame;
        CGRect labelFrame = label.frame;
    
        labelFrame.origin.x = imageFrame.origin.x;
        imageFrame.origin.x = labelFrame.origin.x + CGRectGetWidth(labelFrame);
    
        imageView.frame = imageFrame;
        label.frame = labelFrame;
    }
    • De esta manera es mejor en el caso de que usted necesita para administrar muchos botones, pero necesito cambiar sólo un botón 🙂
    • Si el botón de la imagen es nula la etiqueta resultados fuera de lugar, probablemente debido a que el UIImageView no está insertado (Probado en iOS6.0). Usted debe considerar la modificación de marcos sólo si imageView.la imagen no es nil.
    • Sugiero los siguientes mejora a esta respuesta por lo que ambos puntos de vista permanecer centrado: ‘CGFloat cumulativeWidth = CGRectGetWidth(imageFrame) + CGRectGetWidth(labelFrame) + 10; CGFloat excessiveWidth = CGRectGetWidth(auto.límites) – cumulativeWidth; labelFrame.origen.x = excessiveWidth / 2; imageFrame.origen.x = CGRectGetMaxX(labelFrame) + 10;’
    • De esta forma se rompe en iOS 7 para mí. A alguien más? Funciona bien en iOS 8.
    • No apoyo a iOS7 en todo y el problema habrá desaparecido. Usted no apoya de todos modos.
  5. 30

    ¿Qué acerca de la creación de subclases UIButton y primordial layoutSubviews?

    A continuación, post-procesamiento de los lugares de self.imageView & self.titleLabel

    • Esto es mucho más fácil que todos los otros consejos (como la de arriba) sobre tratando de hacer todo correctamente usando la mano de sintonía insertos.
  6. 12

    Otra manera simple (que NO es iOS 9) es subclase UIButton para anular estos dos métodos

    override func titleRectForContentRect(contentRect: CGRect) -> CGRect {
        var rect = super.titleRectForContentRect(contentRect)
        rect.origin.x = 0
        return rect
    }
    
    override func imageRectForContentRect(contentRect: CGRect) -> CGRect {
        var rect = super.imageRectForContentRect(contentRect)
        rect.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(rect)
        return rect
    }

    contentEdgeInsets ya ha sido tomado en cuenta por el uso de super.

    • Gracias! Me gusta mucho más que las respuestas que la subclase y reemplazar layoutSubviews() 🙂
    • La mejor manera de ir sobre esto en mi humilde opinión 🙂
  7. 9

    Obligando ‘a la derecha-a-izquierda» para el botón no es una opción si la aplicación es compatible tanto de «izquierda-derecha» y «derecha a izquierda».

    La solución que funcionó para mí es una subclase que puede ser añadido al botón en el Guión gráfico y funciona bien con restricciones (probado en iOS 11):

    class ButtonWithImageAtEnd: UIButton {
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            if let imageView = imageView, let titleLabel = titleLabel {
                let padding: CGFloat = 15
                imageEdgeInsets = UIEdgeInsets(top: 5, left: titleLabel.frame.size.width+padding, bottom: 5, right: -titleLabel.frame.size.width-padding)
                titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageView.frame.width, bottom: 0, right: imageView.frame.width)
            }
    
        }
    
    }

    Donde ‘relleno’ sería el espacio entre el título y la imagen.

    • Por supuesto .forceRightToLeft es una opción! Sólo utilice el valor opuesto (.forceLeftToRight) si UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft.
  8. 5

    En Swift:

    override func layoutSubviews(){
        super.layoutSubviews()
    
        let inset: CGFloat = 5
    
        if var imageFrame = self.imageView?.frame,
           var labelFrame = self.titleLabel?.frame {
    
           let cumulativeWidth = imageFrame.width + labelFrame.width + inset
           let excessiveWidth = self.bounds.width - cumulativeWidth
           labelFrame.origin.x = excessiveWidth / 2
           imageFrame.origin.x = labelFrame.origin.x + labelFrame.width + inset
    
           self.imageView?.frame = imageFrame
           self.titleLabel?.frame = labelFrame  
        }
    }
  9. 4

    Edificio de la respuesta por @split…

    La respuesta es fantástico, pero ignora el hecho de que el botón de encargo de la imagen y el título de borde de los márgenes establecidos de antemano (por ejemplo, en el guión gráfico).

    Por ejemplo, puede que desee que la imagen tiene algo de relleno de la parte superior y la parte inferior del recipiente, pero todavía se puede mover la imagen a la derecha del botón.

    He ampliado el concepto con este método:-

    - (void) moveImageToRightSide {
        [self sizeToFit];
    
        CGFloat titleWidth = self.titleLabel.frame.size.width;
        CGFloat imageWidth = self.imageView.frame.size.width;
        CGFloat gapWidth = self.frame.size.width - titleWidth - imageWidth;
        self.titleEdgeInsets = UIEdgeInsetsMake(self.titleEdgeInsets.top,
                                                -imageWidth + self.titleEdgeInsets.left,
                                                self.titleEdgeInsets.bottom,
                                                imageWidth - self.titleEdgeInsets.right);
    
        self.imageEdgeInsets = UIEdgeInsetsMake(self.imageEdgeInsets.top,
                                                titleWidth + self.imageEdgeInsets.left + gapWidth,
                                                self.imageEdgeInsets.bottom,
                                                -titleWidth + self.imageEdgeInsets.right - gapWidth);
    }
  10. 2
    //Get the size of the text and image
    CGSize buttonLabelSize = [[self.button titleForState:UIControlStateNormal] sizeWithFont:self.button.titleLabel.font];
    CGSize buttonImageSize = [[self.button imageForState:UIControlStateNormal] size];
    
    //You can do this line in the xib too:
    self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
    
    //Adjust Edge Insets according to the above measurement. The +2 adds a little space 
    self.button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, -(buttonLabelSize.width+2));
    self.button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, buttonImageSize.width+2);

    Esto crea un alineado a la derecha del botón, así:

    [           button label (>)]

    El botón no se ajuste a la anchura de acuerdo con el contexto, por lo que el espacio aparecerá a la izquierda de la etiqueta. Usted podría solucionar esto mediante el cálculo de la anchura del marco de la buttonLabelSize.la anchura y la buttonImageSize.la anchura.

  11. 1
    button.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
  12. 0

    Esta solución funciona con iOS 7 y por encima de

    Sólo subclase UIButton

    @interface UIButton (Image)
    
    - (void)swapTextWithImage;
    
    @end
    
    @implementation UIButton (Image)
    
    - (void)swapTextWithImage {
       const CGFloat kDefaultPadding = 6.0f;
       CGSize buttonSize = [self.titleLabel.text sizeWithAttributes:@{
                                                                   NSFontAttributeName:self.titleLabel.font
                                                                   }];
    
       self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView.frame.size.width, 0, self.imageView.frame.size.width);
       self.imageEdgeInsets = UIEdgeInsetsMake(0, buttonSize.width + kDefaultPadding, 0, -buttonSize.width); 
    }
    
    @end

    De uso (en Algún lugar en su clase):

    [self.myButton setTitle:@"Any text" forState:UIControlStateNormal];
    [self.myButton swapTextWithImage];
  13. 0

    Edificio en respuestas anteriores. Si usted desea tener un margen de entre el icono y el título del botón, el código tiene que cambiar un poco para evitar la flotación de la etiqueta y el icono por encima de los límites de intrínsecamente tamaño de los botones.

    let margin = CGFloat(4.0)
    button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
    button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width)
    button.contentEdgeInsets = UIEdgeInsetsMake(0, margin, 0, margin)

    La última línea de código es importante para el contenido intrínsecamente tamaño de cálculo para el diseño automático.

  14. 0

    Aquí está mi propia manera de hacer las cosa, (después de unos 10 años)

    1. Subclase de UIButton (Botón, como las que estamos viviendo en Swift era)
    2. Poner una imagen y una etiqueta en una pila de vista.
    class CustomButton: Button {
    
        var didLayout: Bool = false //The code must be called only once
    
        override func layoutSubviews() {
            super.layoutSubviews()
            if !didLayout, let imageView = imageView, let titleLabel = titleLabel {
                didLayout = true
                let stack = UIStackView(arrangedSubviews: [titleLabel, imageView])
                addSubview(stack)
                stack.edgesToSuperview() //I use TinyConstraints library. You could handle the constraints directly
                stack.axis = .horizontal
            }
        }
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea