wake-up-neo.com

iPhone UIButton - Bildposition

Ich habe eine UIButton mit dem Text "Explore the app" und UIImage (>) In Interface Builder sieht es aus:

[ (>) Explore the app ]

Aber ich muss diese UIImage NACH dem Text platzieren:

[ Explore the app (>) ]

Wie kann ich die UIImage nach rechts verschieben?

108
Pavel Yakimenko

Das Erzwingen von "rechts nach links" für die Schaltfläche ist keine Option, wenn Ihre App sowohl "links nach rechts" als auch "rechts nach links" unterstützt.

Die Lösung, die für mich funktioniert hat, ist eine Unterklasse, die der Schaltfläche im Storyboard hinzugefügt werden kann und mit Einschränkungen funktioniert (getestet in 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)
        }

    }

}

Wobei Padding der Abstand zwischen Titel und Bild wäre.

5
Luisma

Meine Lösung dazu ist ziemlich einfach

[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);
159
Split

Auf iOS 9 scheint es eine einfache Möglichkeit zu sein, die Semantik der Ansicht zu erzwingen.

 enter image description here

Oder programmgesteuert mit: 

button.semanticContentAttribute = .ForceRightToLeft
110
Alvivi

Stellen Sie die Variable imageEdgeInset und titleEdgeInset ein, um die Komponenten in Ihrem Bild zu verschieben. Sie können auch eine Schaltfläche erstellen, die Grafiken in voller Größe verwendet, und diese als Hintergrundbild für die Schaltfläche verwenden (verwenden Sie dann titleEdgeInsets, um den Titel zu verschieben).

83
Steven Canfield

Raymond Ws Antwort ist hier am besten. UIButton-Unterklasse mit benutzerdefiniertem LayoutSubviews. Sehr einfach zu machen, hier ist eine Implementierung von layoutSubviews, die für mich funktioniert hat:

- (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;
}
54
Chris Miles

Was ist mit der Unterklasse UIButton und dem Überschreiben von layoutSubviews?

Anschließend die Orte von self.imageView & self.titleLabel nachbearbeiten

30
Raymond W

Eine andere einfache Möglichkeit (das ist NICHT nur iOS 9) ist die Unterklasse UIButton, um diese beiden Methoden zu überschreiben

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 wird bereits mit super berücksichtigt.

11
DrAL3X

In Swift:

override func layoutSubviews()
{
    super.layoutSubviews()

    var imageFrame = self.imageView?.frame;
    var labelFrame = self.titleLabel?.frame;

    let inset: CGFloat = 5

    if var imageFrame = imageFrame
    {
        if var labelFrame = labelFrame
        {
            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
        }
    }
}
4
ChikabuZ

Antwort aufbauen durch @split ...

Die Antwort ist fantastisch, ignoriert jedoch die Tatsache, dass die Schaltfläche über ein benutzerdefiniertes Bild und einen vordere Randeinschnitt verfügt (z. B. im Storyboard). 

Beispielsweise möchten Sie, dass das Bild oben und unten im Container etwas aufgefüllt wird, das Bild aber immer noch auf die rechte Seite der Schaltfläche verschoben wird.

Ich habe das Konzept mit dieser Methode erweitert: - 

- (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);
}
4
BFar
// 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);

Dadurch wird eine Schaltfläche rechtsbündig erstellt:

[           button label (>)]

Die Schaltfläche passt die Breite nicht entsprechend dem Kontext an, sodass links neben dem Etikett ein Leerzeichen angezeigt wird. Sie können dies lösen, indem Sie die Rahmenbreite der Schaltfläche aus der Schaltfläche buttonLabelSize.width und der buttonImageSize.width berechnen.

2
caliss
button.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
1
Todd Vanderlin

Diese Lösung funktioniert für iOS 7 und höher

Nur Unterklasse 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

Nutzung (irgendwo in Ihrer Klasse):

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

Aufbau auf früheren Antworten. Wenn Sie einen Abstand zwischen dem Symbol und dem Titel der Schaltfläche haben möchten, muss der Code ein wenig geändert werden, um ein Verschieben der Beschriftung und des Symbols über die Grenzen der Schaltflächen zu verhindern.

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)

Die letzte Codezeile ist wichtig für die Berechnung der intrinsischen Inhaltsgröße für das automatische Layout. 

0
Kie