Programing

UIButton의 iOS NSAttributedString

crosscheck 2021. 1. 7. 19:41
반응형

UIButton의 iOS NSAttributedString


내가 사용하고 아이폰 OS 6 , 그래서 기인 문자열을 쉽게 사용할 수 있어야한다, 권리? 글쎄 ...별로.

내가하고 싶은 것 :

의 사용자 지정 하위 클래스를 사용하여 (에 사용자 지정 UIButton작업을 수행하지 않음 titleLabel) 다음과 같은 여러 줄로 된 제목을 갖고 싶습니다.

  1. 첫 번째 줄의 모든 대문자 (속성의 일부가 아님)
  2. 첫 줄에 굵게 표시
  3. 첫 번째 줄에 밑줄
  4. 두 번째 줄의 "정상"가중치
  5. 두 번째 줄에 밑줄 없음
  6. 두 줄 중심

나는 지금까지 #의 1부터 5까지를 얻을 수 있었다 (적어도 내가 생각했지만 현재 테스트에서 여러 줄 텍스트로 오류가 발생 함). 텍스트가 중앙에 오면 내 앱이 계속 충돌합니다. 다양한 방법을 통해 6 개 항목을 모두 작동 시키려고하면 다음과 같은 충돌 / 오류가 발생합니다.

Terminating app due to uncaught exception 
'NSInternalInconsistencyException', reason: 
'NSAttributedString invalid for autoresizing, 
it must have a single spanning paragraph style
(or none) with a non-wrapping lineBreakMode.'

내가 시도한 바에 따르면 다음 옵션 중 하나를 가질 수 있지만 둘 다 가질 수는 없습니다.

  1. 여러 줄로 된 중앙 레이블
  2. 속성 라벨

해야 한다면 둘 중 하나와 함께 살 수 있지만, 상당히 간단한 개념으로 보이는 것을 가질 수 없다는 것을 믿을 수 없습니다.

누군가 내가 뭘 잘못했는지 말해 줄 수 있습니까?

내가 시도하는 코드의 마지막 반복은 다음과 같습니다.

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];

UIFont *font1 = [UIFont fontWithName:@"HelveticaNeue-Medium" size:20.0f];
UIFont *font2 = [UIFont fontWithName:@"HelveticaNeue-Light"  size:20.0f];
NSDictionary *dict1 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),  
                        NSFontAttributeName:font1};
NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone),    
                        NSFontAttributeName:font2};

NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"LINE 1\n"    attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"line 2"      attributes:dict2]];
[[self buttonToStyle] setAttributedTitle:attString forState:UIControlStateNormal];
[[[self buttonToStyle] titleLabel] setNumberOfLines:0];
[[[self buttonToStyle] titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];

설정 한 "스타일"개체를 사용하는 코드를 잊은 것 같습니다. 방금 인스턴스화했습니다. 다음과 같이 코드를 수정해야합니다.

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];

UIFont *font1 = [UIFont fontWithName:@"HelveticaNeue-Medium" size:20.0f];
UIFont *font2 = [UIFont fontWithName:@"HelveticaNeue-Light"  size:20.0f];
NSDictionary *dict1 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),
                        NSFontAttributeName:font1,
                        NSParagraphStyleAttributeName:style}; // Added line
NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone),
                        NSFontAttributeName:font2,
                        NSParagraphStyleAttributeName:style}; // Added line

NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"LINE 1\n"    attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"line 2"      attributes:dict2]];
[self.resolveButton setAttributedTitle:attString forState:UIControlStateNormal];
[[self.resolveButton titleLabel] setNumberOfLines:0];
[[self.resolveButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];

NSParagraphStyleAttributeName ..을 정의하는 줄만 추가했습니다. 다른 모든 것은 동일합니다 .. 버튼에 대해 얻은 결과입니다.

여기에 이미지 설명 입력

그리고 여기 Swift 3.0에 있습니다.

let style = NSMutableParagraphStyle()
style.alignment = .center
style.lineBreakMode = .byWordWrapping

guard
    let font1 = UIFont(name: "HelveticaNeue-Medium", size: 20),
    let font2 = UIFont(name: "HelveticaNeue-Light", size: 20)  else { return }

let dict1:[String:Any] = [
    NSUnderlineStyleAttributeName:NSUnderlineStyle.styleSingle.rawValue,
    NSFontAttributeName:font1,
    NSParagraphStyleAttributeName:style
]

let dict2:[String:Any] = [
    NSUnderlineStyleAttributeName:NSUnderlineStyle.styleNone.rawValue,
    NSFontAttributeName:font2,
    NSParagraphStyleAttributeName:style
]

let attString = NSMutableAttributedString()
attString.append(NSAttributedString(string: "LINE 1", attributes: dict1))
attString.append(NSAttributedString(string: "line 2", attributes: dict2))

button.setAttributedTitle(attString, for: .normal)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byWordWrapping

Swift 4를 사용하면 UIButton문제를 해결하기 위해 아래 하위 클래스 구현을 사용할 수 있습니다 .

import UIKit

class CustomButton: UIButton {

    required init(title: String, subtitle: String) {
        super.init(frame: CGRect.zero)

        let style = NSMutableParagraphStyle()
        style.alignment = NSTextAlignment.center
        style.lineBreakMode = NSLineBreakMode.byWordWrapping

        let titleAttributes: [NSAttributedStringKey : Any] = [
            NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue,
            NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.largeTitle),
            NSAttributedStringKey.paragraphStyle : style
        ]
        let subtitleAttributes = [
            NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.body),
            NSAttributedStringKey.paragraphStyle : style
        ]

        let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
        attributedString.append(NSAttributedString(string: "\n"))
        attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))

        setAttributedTitle(attributedString, for: UIControlState.normal)
        titleLabel?.numberOfLines = 0
        titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

용법:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = CustomButton(title: "Title", subtitle: "Subtitle")
        button.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(button)

        let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    }

}

실제로 버튼 유형이 필요한 경우 대안으로 system다음 코드를 사용할 수 있습니다.

import UIKit

extension UIButton {

    static func customSystemButton(title: String, subtitle: String) -> UIButton {            
        let style = NSMutableParagraphStyle()
        style.alignment = NSTextAlignment.center
        style.lineBreakMode = NSLineBreakMode.byWordWrapping

        let titleAttributes: [NSAttributedStringKey : Any] = [
            NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue,
            NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.largeTitle),
            NSAttributedStringKey.paragraphStyle : style
        ]
        let subtitleAttributes = [
            NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: UIFontTextStyle.body),
            NSAttributedStringKey.paragraphStyle : style
        ]

        let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
        attributedString.append(NSAttributedString(string: "\n"))
        attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))

        let button = UIButton(type: UIButtonType.system)
        button.setAttributedTitle(attributedString, for: UIControlState.normal)
        button.titleLabel?.numberOfLines = 0
        button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

        return button
    }

}

용법:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton.customSystemButton(title: "Title", subtitle: "Subtitle")
        button.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(button)

        let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    }

}

아래의 두 스크린 샷은 UIButton하위 클래스 (왼쪽) 및 system유형 버튼 (오른쪽)에 대한 결과 디스플레이를 보여줍니다 .

여기에 이미지 설명 입력

참조 URL : https://stackoverflow.com/questions/17756067/ios-nsattributedstring-on-uibutton

반응형