Są dwa pytania.
Zastanawiałem się, czy możliwe jest utworzenie UIButton z dwoma wierszami tekstu
Jest to możliwe za pomocą scenorysu lub programowo.
Storyboard:
Zmień „Tryb łamania wiersza” na Zawijanie znaków lub Zawijanie słów i użyj klawisza Alt / Opcja + Enter , aby wprowadzić nowy wiersz w polu Tytuł UIButton.
Programowo:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}
Każdy wiersz powinien mieć inny rozmiar czcionki 1
W najgorszym przypadku możesz użyć własnej UIButton
klasy i dodać do niej dwie etykiety.
Lepszym sposobem jest skorzystanie z NSMutableAttributedString
. Należy zauważyć, że można to osiągnąć tylko programowo.
Swift 5:
@IBOutlet weak var btnTwoLine: UIButton?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
let buttonText: NSString = "hello\nthere"
let newlineRange: NSRange = buttonText.range(of: "\n")
var substring1 = ""
var substring2 = ""
if(newlineRange.location != NSNotFound) {
substring1 = buttonText.substring(to: newlineRange.location)
substring2 = buttonText.substring(from: newlineRange.location)
}
let font1: UIFont = UIFont(name: "Arial", size: 17.0)!
let attributes1 = [NSMutableAttributedString.Key.font: font1]
let attrString1 = NSMutableAttributedString(string: substring1, attributes: attributes1)
let font2: UIFont = UIFont(name: "Arial", size: 11.0)!
let attributes2 = [NSMutableAttributedString.Key.font: font2]
let attrString2 = NSMutableAttributedString(string: substring2, attributes: attributes2)
attrString1.append(attrString2)
textResponseButton?.setAttributedTitle(attrString1, for: [])
}
Starszy Szybki
@IBOutlet weak var btnTwoLine: UIButton?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
var buttonText: NSString = "hello\nthere"
var newlineRange: NSRange = buttonText.rangeOfString("\n")
var substring1: NSString = ""
var substring2: NSString = ""
if(newlineRange.location != NSNotFound) {
substring1 = buttonText.substringToIndex(newlineRange.location)
substring2 = buttonText.substringFromIndex(newlineRange.location)
}
let font:UIFont? = UIFont(name: "Arial", size: 17.0)
let attrString = NSMutableAttributedString(
string: substring1 as String,
attributes: NSDictionary(
object: font!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
let font1:UIFont? = UIFont(name: "Arial", size: 11.0)
let attrString1 = NSMutableAttributedString(
string: substring2 as String,
attributes: NSDictionary(
object: font1!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
attrString.appendAttributedString(attrString1)
btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)
}
Wynik
Szukałem prawie tego samego tematu, z tym że nie potrzebuję dwóch różnych rozmiarów czcionek. W przypadku, gdy ktoś szuka prostego rozwiązania:
let button = UIButton() button.titleLabel?.numberOfLines = 0 button.titleLabel?.lineBreakMode = .byWordWrapping button.setTitle("Foo\nBar", for: .normal) button.titleLabel?.textAlignment = .center button.sizeToFit() button.addTarget(self, action: #selector(rightBarButtonTapped), for: .allEvents) navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
źródło
Zauważyłem problem w większości rozwiązań polegający na tym, że podczas przełączania trybu łamania linii na "Zawijanie znaków" druga linia zostanie wyrównana do pierwszej linii
Aby wszystkie linie były wyśrodkowane. po prostu zmień tytuł ze zwykłego na przypisany, a następnie możesz wyśrodkować każdą linię
źródło
zmień podział wiersza na zawijanie znaków, wybierz przycisk iw Inspektorze atrybutów przejdź do podziału wiersza i zmień go na zawijanie znaków
źródło
Składnia SWIFT 3
let str = NSMutableAttributedString(string: "First line\nSecond Line") str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 17), range: NSMakeRange(0, 10)) str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(11, 11)) button.setAttributedTitle(str, for: .normal)
źródło
Naprawiłem to i moje rozwiązanie było tylko w Storyboard.
Zmiany:
Dodano w Inspektor tożsamości -> Atrybuty środowiska uruchomieniowego zdefiniowane przez użytkownika (te KeyPaths):
Atrybuty środowiska wykonawczego zdefiniowane przez użytkownika
Dodałem to w inspektorze atrybutów:
Zawijanie tekstu
źródło
Musisz to zrobić w kodzie. nie możesz ustawić 2 różnych czcionek w IB. Oprócz zmiany trybu łamania linii na zawijanie znaków, potrzebujesz czegoś takiego, aby ustawić tytuł,
override func viewDidLoad() { super.viewDidLoad() var str = NSMutableAttributedString(string: "First line\nSecond Line") str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(17), range: NSMakeRange(0, 10)) str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12), range: NSMakeRange(11, 11)) button.setAttributedTitle(str, forState: .Normal) }
źródło
Myślę, że jednym ze sposobów jest użycie etykiet. Zrobiłem to i wydaje się, że działa dobrze. Mógłbym stworzyć to jako UIButton, a potem chyba wyeksponować etykiety. Nie wiem, czy to ma sens.
let firstLabel = UILabel() firstLabel.backgroundColor = UIColor.lightGrayColor() firstLabel.text = "Hi" firstLabel.textColor = UIColor.blueColor() firstLabel.textAlignment = NSTextAlignment.Center firstLabel.frame = CGRectMake(0, testButton.frame.height * 0.25, testButton.frame.width, testButton.frame.height * 0.2) testButton.addSubview(firstLabel) let secondLabel = UILabel() secondLabel.backgroundColor = UIColor.lightGrayColor() secondLabel.textColor = UIColor.blueColor() secondLabel.font = UIFont(name: "Arial", size: 12) secondLabel.text = "There" secondLabel.textAlignment = NSTextAlignment.Center secondLabel.frame = CGRectMake(0, testButton.frame.height * 0.5, testButton.frame.width, testButton.frame.height * 0.2) testButton.addSubview(secondLabel)
źródło
Moja droga:
func setButtonTitle(title: String, subtitle: String, button: UIButton){ //applying the line break mode button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping; let title = NSMutableAttributedString(string: title, attributes: Attributes.biggestLabel) let subtitle = NSMutableAttributedString(string: subtitle, attributes: Attributes.label) let char = NSMutableAttributedString(string: "\n", attributes: Attributes.biggestLabel) title.append(char) title.append(subtitle) button.setAttributedTitle(title, for: .normal) }
źródło
Sugerowane rozwiązania niestety nie zadziałały, gdy chciałem mieć przycisk mutliline wewnątrz CollectionView. Następnie kolega pokazał mi obejście, którym chciałbym się podzielić na wypadek, gdyby ktoś miał ten sam problem - mam nadzieję, że to pomoże! Utwórz klasę, która dziedziczy po UIControl i rozszerz ją o etykietę, która będzie wtedy zachowywać się podobnie jak przycisk.
class MultilineButton: UIControl { let label: UILabel = { $0.translatesAutoresizingMaskIntoConstraints = false $0.numberOfLines = 0 $0.textAlignment = .center return $0 }(UILabel()) override init(frame: CGRect) { super.init(frame: frame) addSubview(label) NSLayoutConstraint.activate([ label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor), label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) ]) } override var isHighlighted: Bool { didSet { backgroundColor = backgroundColor?.withAlphaComponent(isHighlighted ? 0.7 : 1.0) label.textColor = label.textColor.withAlphaComponent(isHighlighted ? 0.7 : 1.0) } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
źródło