Swift-두 줄의 텍스트가있는 UIButton


93

두 줄의 텍스트로 UIButton을 만들 수 있는지 궁금합니다. 다른 글꼴 크기를 가지려면 각 줄이 필요합니다. 첫 번째 라인은 17 포인트가되고 두 ​​번째 라인은 11 포인트가됩니다. UIButton 내부에 두 개의 레이블을 넣는 것을 엉망으로 만들었지 만 단추 경계 안에 머물도록 만들 수 없습니다.

프로그래밍 방식이 아닌 UI 빌더에서이 모든 작업을 수행하려고합니다.

감사

답변:


248

두 가지 질문이 있습니다.

두 줄의 텍스트로 UIButton을 만들 수 있는지 궁금합니다.

이것은 스토리 보드를 사용하거나 프로그래밍 방식으로 가능합니다.

스토리 보드 :

에 '줄 바꿈 모드'로 변경 문자 랩 또는 줄 바꿈을 하고 사용 Alt 키 / 옵션 + Enter를 있는 UIButton의 제목 필드에 새 줄을 입력 키를.

여기에 이미지 설명 입력

프로그래밍 방식 :

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}

다른 글꼴 크기를 가지려면 각 줄이 필요합니다 1

최악의 경우는 사용자 정의 UIButton클래스를 사용하고 그 안에 두 개의 레이블을 추가 할 수 있다는 것입니다.

더 좋은 방법은 NSMutableAttributedString. 이것은 프로그래밍 방식으로 만 달성 할 수 있습니다.

스위프트 5 :

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //applying the line break mode
    textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
    let buttonText: NSString = "hello\nthere"

    //getting the range to separate the button title strings
    let newlineRange: NSRange = buttonText.range(of: "\n")

    //getting both substrings
    var substring1 = ""
    var substring2 = ""

    if(newlineRange.location != NSNotFound) {
        substring1 = buttonText.substring(to: newlineRange.location)
        substring2 = buttonText.substring(from: newlineRange.location)
    }

    //assigning diffrent fonts to both substrings
    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)

    //appending both attributed strings
    attrString1.append(attrString2)

    //assigning the resultant attributed strings to the button
    textResponseButton?.setAttributedTitle(attrString1, for: [])
}

이전 Swift

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        //applying the line break mode
        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;

        var buttonText: NSString = "hello\nthere"

        //getting the range to separate the button title strings
        var newlineRange: NSRange = buttonText.rangeOfString("\n")

        //getting both substrings
        var substring1: NSString = ""
        var substring2: NSString = ""

        if(newlineRange.location != NSNotFound) {
            substring1 = buttonText.substringToIndex(newlineRange.location)
            substring2 = buttonText.substringFromIndex(newlineRange.location)
        }

        //assigning diffrent fonts to both substrings
        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])

        //appending both attributed strings
        attrString.appendAttributedString(attrString1)

        //assigning the resultant attributed strings to the button
        btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)

    }

산출

여기에 이미지 설명 입력


2
잘 작동합니다. 이제 각 줄에 텍스트를 가운데에 배치 할 방법이 있는지, 두 줄 사이에 더 많은 공간을 삽입 할 방법이 있는지 궁금합니다.
스콧

3
두 줄 텍스트를 가운데에 맞출 수 있습니다. 다음 코드를 작성하십시오 btnTwoLine? .titleLabel? .textAlignment = NSTextAlignment.Center 또는 스토리 보드 파일 (control
section-

사이에 더 많은 줄을 넣는 목적이 무엇인지 알 수 있습니까?
Shamsudheen TK

버튼의 크기에 따라 다릅니다. 버튼이 크면 두 줄의 텍스트가 가운데에 있고 상단과 하단에 많은 공간이 있습니다. 그것은 내가하려고했던 모양이 아닙니다.
Scott

여기에 몇 가지 트릭을 적용해야합니다. :) 여러 줄을 사용하여 \ n 사이에 더 많은 줄을 넣을 수 있습니다. 내 말은, "hello \ n \ n \ nthere"는 세 개의 공백을 제공합니다. 그러나 코드를 수정하는 것을 잊지 마십시오. var newlineRange : NSRange = buttonText.rangeOfString ( "\ n \ n \ n")
Shamsudheen TK

22

두 가지 다른 글꼴 크기가 필요하지 않다는 점을 제외하면 거의 동일한 주제를 찾고있었습니다. 누군가가 간단한 해결책을 찾고있는 경우 :

    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)

12

대부분의 솔루션에서 줄 바꿈 모드를 "문자 줄 바꿈"으로 만드는 동안 두 번째 줄이 첫 번째 줄에 정렬되는 문제를 발견했습니다.

모든 선을 중앙에 배치합니다. 제목을 Plain에서 Attributed로 변경 한 다음 각 줄을 가운데로 만들 수 있습니다.

기여 중심 제목


6

줄 바꿈을 문자 줄 바꿈으로 변경하고 버튼을 선택하고 속성 관리자에서 줄 바꿈으로 이동하여 문자 줄 바꿈으로 변경하십시오.

여기에 이미지 설명 입력


6

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)

2
확실하지 왜,하지만 난 한 추가 button.titleLabel .numberOfLines = 0?
budidino

스위프트 4에서 먼저 작동하지 않았습니다. "줄 바꿈"을 "단어 줄 바꿈"으로 설정해야합니다. 감사합니다 남자 :
카란 Alangat

원래의 이전 답변은 다음과 같습니다. stackoverflow.com/a/30679547/5318223
Kiril S.

5

나는 이것을 고쳤고 내 솔루션은 Storyboard에만있었습니다.

변경 사항 :

이 글은 추가 신원 관리자 -> 사용자 정의 런타임 속성 (이 KeyPaths) :

  • numberOfLines = 2
  • titleLabel.textAlignment = 1

사용자 정의 런타임 속성

속성 관리자에 이것을 추가했습니다.

  • 줄 바꿈 = 줄 바꿈

줄 바꿈


2

이 중 일부를 코드에서 수행해야합니다. IB에서는 2 개의 다른 글꼴을 설정할 수 없습니다. 줄 바꿈 모드를 문자 줄 바꿈으로 변경하는 것 외에도 제목을 설정하려면 다음과 같은 것이 필요합니다.

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)

    }

1

한 가지 방법은 레이블을 사용하는 것입니다. 나는 이것을했고 그것은 잘 작동하는 것 같습니다. 이것을 UIButton으로 만든 다음 레이블을 노출 할 수 있습니다. 이게 말이되는지 모르겠어요.

    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)

0

내 방식 :

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)
    }

0

불행히도 제안 된 솔루션은 CollectionView 내부에 다중 버튼을 원할 때 저에게 효과적이지 않았습니다. 그런 다음 동료가 누군가 같은 문제가있을 경우 공유하고 싶은 해결 방법을 보여주었습니다. 도움이 되었기를 바랍니다. UIControl에서 상속하는 클래스를 만들고 레이블로 확장하면 버튼처럼 작동합니다.

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")
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.