Ich bin etwas spät zu dieser Party, aber ich denke, ich habe etwas Nützliches hinzuzufügen.
Kekoas Antwort ist großartig, aber wie RonLugge erwähnt, kann dies dazu führen, dass die Schaltfläche nicht mehr respektiert wird sizeToFit
oder, was noch wichtiger ist, dazu führt, dass die Schaltfläche ihren Inhalt abschneidet, wenn sie eine intrinsische Größe hat. Huch!
Zunächst jedoch
Eine kurze Erklärung, wie ich glaube imageEdgeInsets
und titleEdgeInsets
arbeite:
Die Dokumente fürimageEdgeInsets
haben zum Teil Folgendes zu sagen:
Verwenden Sie diese Eigenschaft, um die Größe zu ändern und das effektive Zeichnungsrechteck für das Schaltflächenbild neu zu positionieren. Sie können für jeden der vier Einschübe (oben, links, unten, rechts) einen anderen Wert angeben. Ein positiver Wert verkleinert oder fügt diese Kante ein und bewegt sie näher an die Mitte der Schaltfläche. Ein negativer Wert erweitert oder verschiebt diese Kante.
Ich glaube, dass diese Dokumentation geschrieben wurde und sich vorstellte, dass der Button keinen Titel hat, nur ein Bild. Es macht viel mehr Sinn, auf diese Weise zu denken, und verhält sich wie UIEdgeInsets
gewöhnlich. Grundsätzlich wird der Bildrahmen (oder der Titel mit titleEdgeInsets
) für positive Einfügungen nach innen und für negative Einfügungen nach außen verschoben.
In Ordnung und jetzt?
Ich komme dahin! Standardmäßig legen Sie ein Bild und einen Titel fest (der Schaltflächenrand ist grün, um anzuzeigen, wo er sich befindet):
Wenn Sie einen Abstand zwischen einem Bild und einem Titel wünschen, ohne dass einer davon beschädigt wird, müssen Sie vier verschiedene Einfügungen festlegen, jeweils zwei für das Bild und den Titel. Das liegt daran, dass Sie nicht die Größe der Rahmen dieser Elemente ändern möchten , sondern nur deren Position. Wenn Sie anfangen, so zu denken, wird die notwendige Änderung in Kekoas ausgezeichneter Kategorie klar:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}
@end
Aber warte , sagst du, wenn ich das mache, bekomme ich folgendes:
Oh ja! Ich habe vergessen, die Dokumente haben mich davor gewarnt. Sie sagen teilweise:
Diese Eigenschaft wird nur zum Positionieren des Bildes während des Layouts verwendet. Die Schaltfläche verwendet diese Eigenschaft nicht, um intrinsicContentSize
und zu bestimmen sizeThatFits:
.
Aber es gibt eine Eigenschaft, die helfen kann, und das ist contentEdgeInsets
. Die Dokumente dazu sagen teilweise:
Die Schaltfläche verwendet diese Eigenschaft, um intrinsicContentSize
und zu bestimmen sizeThatFits:
.
Das klingt gut. Lassen Sie uns die Kategorie noch einmal optimieren:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}
@end
Und was bekommst du?
Sieht für mich wie ein Gewinner aus.
Arbeiten Sie in Swift und möchten Sie überhaupt nicht nachdenken? Hier ist die endgültige Version der Erweiterung in Swift:
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}