Hier ist eine allgemeine Lösung, um das Bild zentriert über dem Text zu positionieren, ohne magische Zahlen zu verwenden. Beachten Sie, dass der folgende Code veraltet ist und Sie wahrscheinlich eine der folgenden aktualisierten Versionen verwenden sollten :
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
Die folgende Version enthält Änderungen zur Unterstützung von iOS 7+ , die in den Kommentaren unten empfohlen wurden. Ich habe diesen Code nicht selbst getestet, daher bin ich mir nicht sicher, wie gut er funktioniert oder ob er bei Verwendung unter früheren iOS-Versionen beschädigt werden würde.
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);
Swift 5.0 Version
extension UIButton {
func alignVertical(spacing: CGFloat = 6.0) {
guard let imageSize = imageView?.image?.size,
let text = titleLabel?.text,
let font = titleLabel?.font
else { return }
titleEdgeInsets = UIEdgeInsets(
top: 0.0,
left: -imageSize.width,
bottom: -(imageSize.height + spacing),
right: 0.0
)
let titleSize = text.size(withAttributes: [.font: font])
imageEdgeInsets = UIEdgeInsets(
top: -(titleSize.height + spacing),
left: 0.0,
bottom: 0.0, right: -titleSize.width
)
let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0
contentEdgeInsets = UIEdgeInsets(
top: edgeOffset,
left: 0.0,
bottom: edgeOffset,
right: 0.0
)
}
}
button.currentTitle
alsbutton.titleLabel.text
insbesondere, wenn sich der Schaltflächentext jemals ändern wird.currentTitle
wird sofort gefüllt, wohingegentitleLabel.text
sich nur langsam ändern kann, was zu falsch ausgerichteten Einschüben führen kann.Gefunden wie.
Konfigurieren Sie zunächst den Text von
titleLabel
(aufgrund von Stilen, dh fett, kursiv usw.). Verwenden Sie dann untersetTitleEdgeInsets
Berücksichtigung der Breite Ihres Bildes:Verwenden Sie danach unter
setTitleEdgeInsets
Berücksichtigung der Breite der Textgrenzen:Jetzt werden das Bild und der Text zentriert (in diesem Beispiel wird das Bild über dem Text angezeigt).
Prost.
quelle
Sie können dies mit dieser Swift-Erweiterung tun, die teilweise auf Jesse Crossens Antwort basierte:
Dies definiert eine Funktion
centerLabelVerticallyWithPadding
, die die Titel- und Bildeinfügungen entsprechend .Außerdem werden die contentEdgeInsets festgelegt, die meiner Meinung nach erforderlich sind, um dies sicherzustellen
intrinsicContentSize
weiterhin ordnungsgemäß funktionieren und das automatische Layout verwenden müssen.Ich glaube, dass alle Lösungen, die UIButton in Unterklassen enthalten, technisch unzulässig sind, da Sie UIKit-Steuerelemente nicht in Unterklassen unterteilen sollen. Das heißt, theoretisch könnten sie in zukünftigen Versionen brechen.
quelle
Bearbeiten: Aktualisiert für Swift 3
Wenn Sie nach einer Swift-Lösung für Jesse Crossens Antwort suchen, können Sie diese zu einer Unterklasse von UIButton hinzufügen:
quelle
Es gibt hier einige großartige Beispiele, aber ich konnte dies nicht in allen Fällen zum Laufen bringen, wenn ich mich auch mit mehreren Textzeilen befasste (Textumbruch). Um es endlich zum Laufen zu bringen, habe ich einige der Techniken kombiniert:
Ich habe oben das Beispiel von Jesse Crossen verwendet. Ich habe jedoch ein Problem mit der Texthöhe behoben und die Möglichkeit hinzugefügt, einen horizontalen Textrand anzugeben. Der Rand ist nützlich, wenn Text umbrochen werden darf, damit er nicht den Rand der Schaltfläche berührt:
Stellen Sie sicher, dass Sie die Textbeschriftung zum Umbrechen einrichten
Dies wird jetzt meistens funktionieren. Ich hatte jedoch einige Schaltflächen, die das Bild nicht richtig wiedergaben. Das Bild wurde entweder nach rechts oder links verschoben (es war nicht zentriert). Daher habe ich eine UIButton-Layout-Überschreibungstechnik verwendet, um die Zentrierung der imageView zu erzwingen.
quelle
Ich habe eine Methode für die Antwort von @ TodCunningham erstellt
quelle
Aktualisiert für Xcode 11+
Die in meiner ursprünglichen Antwort beschriebenen Einfügungen wurden in neueren Versionen von Xcode in den Größeninspektor verschoben. Ich bin nicht zu 100% sicher, wann der Wechsel stattgefunden hat, aber die Leser sollten den Größeninspektor überprüfen, wenn die eingefügten Informationen nicht im Attributinspektor gefunden werden. Unten finden Sie ein Beispiel für den neuen Einschubbildschirm (ab 11.5 oben im Inspektor für Größenattribute).
Ursprüngliche Antwort
An den anderen Antworten ist nichts auszusetzen, ich wollte jedoch nur darauf hinweisen, dass das gleiche Verhalten in Xcode visuell mit null Codezeilen erreicht werden kann. Diese Lösung ist nützlich, wenn Sie keinen berechneten Wert benötigen oder mit einem Storyboard / xib erstellen (andernfalls gelten andere Lösungen).
Hinweis - Ich verstehe, dass die Frage des OP Code erfordert. Ich gebe diese Antwort nur der Vollständigkeit halber und als logische Alternative für diejenigen, die Storyboards / Xibs verwenden.
Um den Abstand in Bild-, Titel- und Inhaltsansichten einer Schaltfläche mithilfe von Kanteneinfügungen zu ändern, können Sie die Schaltfläche / das Steuerelement auswählen und den Attributinspektor öffnen. Scrollen Sie nach unten zur Mitte des Inspektors und suchen Sie den Abschnitt für Kanteneinsätze.
Sie können auch auf die spezifischen Kanteneinfügungen für die Titel-, Bild- oder Inhaltsansicht zugreifen und diese ändern.
quelle
Kämpfe nicht gegen das System. Wenn Ihre Layouts zu komplex werden, um mit Interface Builder + möglicherweise einfachem Konfigurationscode verwaltet zu werden, führen Sie die Layouts auf einfachere Weise manuell aus
layoutSubviews
- dafür ist es da! Alles andere wird Hacks sein.Erstellen Sie eine UIButton-Unterklasse und überschreiben Sie deren
layoutSubviews
Methode, um Text und Bild programmgesteuert auszurichten. Oder verwenden Sie https://github.com/nickpaulson/BlockKit/blob/master/Source/UIView-BKAdditions.h, damit Sie layoutSubviews mithilfe eines Blocks implementieren können.quelle
Unterklasse UIButton
quelle
Aktualisierte Antwort von Jesse Crossen für Swift 4 :
Verwenden Sie diesen Weg:
quelle
Mit diesem Codestück erhalten Sie so etwas
quelle
UIButton-Erweiterung mit Swift 3+ -Syntax :
Ursprüngliche Antwort: https://stackoverflow.com/a/7199529/3659227
quelle
Nur eine kleine Änderung an Jesse Crossens Antwort, die es perfekt für mich gemacht hat:
anstatt:
Ich habe das benutzt:
quelle
Die Verwendung
button.titleLabel.frame.size.width
funktioniert nur, solange das Etikett kurz genug ist, um nicht abgeschnitten zu werden. Wenn der Beschriftungstext abgeschnitten wird, funktioniert die Positionierung jedoch nicht. Nehmenfunktioniert bei mir auch dann, wenn der beschriftungstext abgeschnitten ist.
quelle
Ich habe mir vorhandene Antworten angesehen, aber ich fand auch, dass das Einstellen des Schaltflächenrahmens ein wichtiger erster Schritt ist.
Hier ist eine Funktion, die ich benutze, um das zu erledigen:
quelle
Oder Sie können einfach diese Kategorie verwenden:
quelle
CGSize titleSize = [button.titleLabel.text sizeWithAttributes: @{NSFontAttributeName: button.titleLabel.font}];
Mein Anwendungsfall machte Einfügungen unüberschaubar:
Das habe ich letztendlich gemacht und bin ziemlich zufrieden damit:
Erstellen Sie die Schaltfläche im Storyboard mit einem Hintergrundbild (runder Kreis mit Unschärfe und Farbe).
Deklarieren Sie eine UIImageView in meiner Klasse:
Erstellen Sie eine Bildansichtsinstanz auf init:
Fügen Sie in viewDidLoad der Schaltfläche für unsere Bildansicht eine neue Ebene hinzu und legen Sie die Textausrichtung fest:
Fügen Sie bei der Schaltflächenklickmethode mein ausgewähltes Überlagerungsbild zur Bildansicht hinzu, passen Sie es an das Bild an und zentrieren Sie es in der Schaltfläche, aber verschieben Sie es nach oben 15, damit ich den Textversatz darunter platzieren kann:
Hinweis: Ceilf () ist wichtig, um sicherzustellen, dass es für die Bildqualität an einer Pixelgrenze liegt.
quelle
Angenommen, Sie möchten, dass sowohl Text als auch Bild horizontal zentriert werden, Bild über Text: Zentrieren Sie den Text aus dem Interface Builder und fügen Sie einen oberen Einschub hinzu (um Platz für das Bild zu schaffen). (Lassen Sie den linken Einschub auf 0). Verwenden Sie den Interface Builder, um das Bild auszuwählen. Die tatsächliche Position wird anhand des Codes festgelegt. Machen Sie sich also keine Sorgen, dass die Dinge in IB nicht in Ordnung aussehen. Im Gegensatz zu anderen Antworten oben funktioniert dies tatsächlich auf allen derzeit unterstützten iOS-Versionen (5, 6 und 7).
Verwerfen Sie im Code einfach die Bildansicht der Schaltfläche (indem Sie das Bild der Schaltfläche auf Null setzen), nachdem Sie das Bild aufgenommen haben (dies zentriert auch automatisch den Text, der bei Bedarf umbrochen wird). Instanziieren Sie dann Ihre eigene ImageView mit derselben Bildgröße und demselben Bild und positionieren Sie sie in der Mitte.
Auf diese Weise können Sie das Image weiterhin aus dem Interface Builder auswählen (obwohl es in IB nicht wie im Simulator ausgerichtet wird, andere Lösungen jedoch nicht für alle unterstützten iOS-Versionen kompatibel sind).
quelle
Ich hatte Mühe, dies zu erreichen, weil ich auf dem Konstruktor meiner Ansicht keine Bildgröße und Textbreite erhalten konnte. Zwei kleine Änderungen an Jesses Antwort haben bei mir funktioniert:
Die Änderung sind:
[NSString sizeWithAttributes]
, um die zu erhalten;UIImage
stattUIImageView
quelle
Dies funktioniert gut für mich, für mehrere Schaltflächen mit unterschiedlicher Bildbreite und unterschiedlicher Titellänge:
Unterklasse
UIButton
quelle
Funktioniert gut für die Tastengröße 80x80 Pixel.
quelle
Ich habe einige Anpassungen vorgenommen, um das Bild in der Mitte horizontal auszurichten:
quelle
Ist es obligatorisch, Kanteneinsätze zu verwenden? Wenn nicht, können Sie versuchen, den Bezug zur mittleren übergeordneten Ansicht zu positionieren
quelle
Sie müssen das Bild um die Breite des Textes nach rechts verschieben. Verschieben Sie dann den Text um die Breite des Bildes nach links.
Stellen Sie dann die oberen und unteren Einsätze ein, um die Y-Achse anzupassen. Dies könnte wahrscheinlich auch programmgesteuert erfolgen, sollte jedoch für Ihre Bildgröße konstant sein. Während sich die X-Achsen-Einfügungen basierend auf der Größe der Textbeschriftung in jeder Schaltfläche ändern müssen.
quelle
Fügen Sie diesen Code in der Erweiterung Swift 4.2 hinzu
quelle
Nur um meine 2 Cent hineinzuwerfen, hat das bei mir funktioniert:
quelle