Passen Sie die Schriftgröße von UIButton an die Breite an

121

Ich habe folgenden Code:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, 25, 25);

[[button layer] setCornerRadius:5.0f];
[[button layer] setMasksToBounds:YES];
[[button layer] setBackgroundColor:[[UIColor redColor] CGColor]];
[button.titleLabel setFrame:CGRectMake(0,0, 25, 25)];

[button setTitle:[NSString stringWithFormat:@"%@", [[topics objectAtIndex:indexPath.row] unread]] forState:UIControlStateNormal];

Das Problem ist, dass wenn die Zeichenfolge im Text nicht lang ist, sie gut angezeigt wird (1-2 Ziffern). Wenn es jedoch ziemlich lang ist (3 ++ Ziffer), sehe ich nur einen roten Knopf ohne Text. Wie stelle ich das ein?

Das glaube ich nicht:

[button.titleLabel setAdjustsFontSizeToFitWidth:YES];

macht den Job, richtig?

Stollen
quelle
Es sollte funktionieren, oder theLabel.adjustsFontSizeToFitWidth = YES.
Luke
Es funktioniert vontitleButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
onmyway133

Antworten:

290

Versuche dies:

button.titleLabel.numberOfLines = 1;
button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.lineBreakMode = NSLineBreakByClipping; //<-- MAGIC LINE

Ich bin nicht sicher, warum dies den Trick macht, aber es tut :)

Elibud
quelle
1
danke, während button.titleLabel.lineBreakMode = UILineBreakModeClip; <- MAGIC LINE wird jetzt abgeschrieben
yunas
8
@yunas Ersetzen Sie UILineBreakModeClip durch NSLineBreakByClipping
CodeReaper
1
Nvm, das hat es gerade numberOfLinesauf 0 geändert
Marty
33
button.titleLabel.adjustsFontSizeToFitWidth = YES;

sollte die Arbeit selbst erledigen, wenn Sie das automatische Layout verwenden und eine Einschränkung für die Breite der Schaltfläche festgelegt haben.

Die anderen Optionen (minimaler Skalierungsfaktor, Anzahl der Zeilen usw.) können weiterhin verwendet werden, um weitere Anpassungen an Ihre Anforderungen vorzunehmen, sind jedoch nicht erforderlich.

Joakim
quelle
15

Die Antwort von EliBud funktioniert unter iOS 8 nicht. Ich habe eine Lösung gefunden, die unter iOS 8 funktioniert. Nachfolgend finden Sie einen schnellen Code:

let label = self.button?.titleLabel
label?.minimumScaleFactor = 0.01
label?.adjustsFontSizeToFitWidth = true
label?.font = UIFont.systemFontOfSize(100)

Sie können mit dem Label? .LineBreakMode spielen, da ich festgestellt habe, dass die Ergebnisse für verschiedene Unterbrechungsmodi variieren.

Alexander Belyavskiy
quelle
.adjustsFontSizeToFitWidth = true - Wie kann ich dasselbe mit einem NSTextField und einem Fenster mit veränderbarer Größe tun?
Leo Dabus
Das sieht für mich genauso aus, als würde man Xcode IB verwenden, um ein Etikett auszuwählen und es auf Autoshrink-Mindestschriftgröße auf 0,01
einzustellen
Es gibt keine AutoShrink-Option bei Verwendung von NSTextField
Leo Dabus
UITextField bietet eine Option zum automatischen Verkleinern von Text, NSTextField hingegen nicht. Ich denke, Sie müssen die Schriftart manuell an die Breite des Textfelds anpassen.
Alexander Belyavskiy
10

In letzter Zeit scheint dies für mich zu funktionieren

button.titleLabel!.numberOfLines = 1
button.titleLabel!.adjustsFontSizeToFitWidth = true
button.titleLabel!.lineBreakMode = NSLineBreakMode.ByClipping
Tolbard
quelle
10

iOS 10.3-Lösung basierend auf den anderen Antworten hier:

    button.titleLabel!.numberOfLines = 1
    button.titleLabel!.adjustsFontSizeToFitWidth = true
    button.titleLabel!.baselineAdjustment = .alignCenters

baselineAdjustmentNoch niemand erwähnt ; Ich brauchte es, weil die Tastenbeschriftung nach dem adjustsFontSizeToFitWidthWirksamwerden vertikal falsch ausgerichtet wird. Apples baselineAdjustmentDokumentation:

Wenn die adjustsFontSizeToFitWidthEigenschaft auf festgelegt ist true, steuert diese Eigenschaft das Verhalten der Textbasislinien in Situationen, in denen eine Anpassung der Schriftgröße erforderlich ist. Der Standardwert dieser Eigenschaft ist alignBaselines. Diese Eigenschaft ist nur wirksam, wenn die numberOfLinesEigenschaft auf festgelegt ist 1.


FWIW, ich konnte das Etikett nie perfekt ausrichten.

Welpe
quelle
8

adjustsFontSizeToFitWidth funktionierte nicht für mich, bis ich in Interface Builder eine Breitenbeschränkung für meine Schaltfläche festgelegt habe.

Durch das Festlegen der Einschränkung wurde verhindert, dass die Schaltfläche größer wurde, und daher wurde nicht erkannt, dass der Text verkleinert werden musste.

Kraftydevil
quelle
8

Swift 4 Erweiterung

extension UIButton {
    @IBInspectable var adjustFontSizeToWidth: Bool {
        get {
            return self.titleLabel?.adjustsFontSizeToFitWidth
        }
        set {
            self.titleLabel?.numberOfLines = 1
            self.titleLabel?.adjustsFontSizeToFitWidth = newValue;
            self.titleLabel?.lineBreakMode = .byClipping;
            self.titleLabel?.baselineAdjustment = .alignCenters 
        }
    }
}

Geben Sie hier die Bildbeschreibung ein

Nik Kov
quelle
Wofür benutzt du das Tag?
Zaporozhchenko Oleksandr
Für verfügbar sein, um den Getter zu machen
Nik Kov
Können Sie bitte genauer beschreiben, was Sie meinen?
Zaporozhchenko Oleksandr
Ich benutze ein Tag wie ein Flag, um zu definieren, ob die Anpassung aktiviert ist.
Nik Kov
Warum verwendest du nicht einfach self.titleLabel? .adjustsFontSizeToFitWidth? Wofür brauchst du etwas extra?
Zaporozhchenko Oleksandr
3

Xamarin.iOS-Lösung

var accountButton = new UIButton();
accountButton.SetTitle("Account", UIControlState.Normal);            
accountButton.TitleLabel.AdjustsFontSizeToFitWidth = true;
accountButton.TitleLabel.Lines = 1;
accountButton.TitleLabel.LineBreakMode = UILineBreakMode.Clip;
accountButton.TitleLabel.Font = accountButton.TitleLabel.Font.WithSize(35);

Am Ende habe ich die Schriftgröße festgelegt, um sicherzustellen, dass die Schrift "groß" ist, bevor das System die Größe anpasst.

ben
quelle
3

basierend auf Nik Kovs Antwort:

import UIKit


    extension UIButton {
        @IBInspectable var adjustFontSizeToWidth: Bool {
            get {
                return titleLabel!.adjustsFontSizeToFitWidth
            }
            set {
                titleLabel!.adjustsFontSizeToFitWidth = newValue
                titleLabel!.lineBreakMode             = .byClipping
            }
        }
    }
Zaporozhchenko Oleksandr
quelle
Dies funktioniert, aber die Schriftgröße wird stark verringert, z. B. von 17 auf 12. Gibt es eine Möglichkeit, die Breite des Titeletiketts zu erhöhen, wenn die Zeichenfolge größer ist?
R. Mohan
@ R.Mohan sicher, aber das alles über feste Breite. Machen Sie einfach nicht festgelegte Einschränkungen, und es wird wachsen. Setzen Sie nicht beide führenden / nachlaufenden oder machen Sie eine von ihnen> =
Zaporozhchenko Oleksandr
0

Die folgende Lösung hat bei mir funktioniert:

button.titleLabel?.adjustsFontForContentSizeCategory = true

In der Entwicklerdokumentation wird diese Eigenschaft wie folgt erläutert:

Ein boolescher Wert, der angibt, ob das Objekt seine Schriftart automatisch aktualisiert, wenn sich die Inhaltsgrößenkategorie des Geräts ändert.

Vinayak
quelle
0

In iOS 13.1 mit Swift 5 musste ich contentEdgeInsetsauch die Polster anpassen.

extension UIButton {
    @IBInspectable var adjustFontSizeToWidth: Bool {
        get {
            return self.titleLabel?.adjustsFontSizeToFitWidth ?? false
        }
        set {
            self.titleLabel?.numberOfLines = 1
            self.titleLabel?.adjustsFontSizeToFitWidth = newValue;
            self.titleLabel?.lineBreakMode = .byClipping;
            self.titleLabel?.baselineAdjustment = .alignCenters
            self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        }
    }
}
Bharat
quelle