Program Club

iOS 8에서 NSMutableAttributedString을 사용하는 문자열의 밑줄 부분이 작동하지 않습니다.

proclub 2020. 12. 6. 22:16
반응형

iOS 8에서 NSMutableAttributedString을 사용하는 문자열의 밑줄 부분이 작동하지 않습니다.


예를 들어 ' test string'string' string '부분과 같이 문자열 의 일부에 밑줄을 긋습니다 . 나는 사용 하고 있으며 내 솔루션은 .NSMutableAttributedStringiOS7

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
        initWithString:@"test string"];
[attributedString addAttribute:NSUnderlineStyleAttributeName
                         value:@(NSUnderlineStyleSingle)
                         range:NSMakeRange(5, 6)];
myLabel.attributedText = attributedString;

문제는 내 솔루션이 iOS8더 이상 작동하지 않는다는 것입니다. 의 여러 변형을 테스트하는 데 한 시간을 소비 한 후이 NSMutableAttributedString솔루션은 범위가 0으로 시작될 때만 작동한다는 것을 알았습니다 (길이는 다를 수 있음). 그 이유는 무엇입니까? 이 문제를 어떻게 해결할 수 있습니까?


업데이트 : 이 질문을 조사 하여 iOS 8에서 NSMutableAttributedString 표시 마침내 해결책을 찾았습니다!

문자열 시작 부분에 NSUnderlineStyleNone을 추가해야합니다.

Swift 4.2 ( none제거됨) :

let attributedString = NSMutableAttributedString()
attributedString.append(NSAttributedString(string: "test ",
                                           attributes: [.underlineStyle: 0]))
attributedString.append(NSAttributedString(string: "s",
                                           attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue]))
attributedString.append(NSAttributedString(string: "tring",
                                           attributes: [.underlineStyle: 0]))

목표 -C :

 NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"test "
                                                                          attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"s"
                                                                         attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
                                                                                      NSBackgroundColorAttributeName: [UIColor clearColor]}]];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"tring"]];

이러한 접근 방식의 또 다른 이점은 범위가 없다는 것입니다. 현지화 된 문자열에 매우 좋습니다.

Apple 버그 인 것 같습니다.


UnderlineStyleNone을 전체 문자열에 적용하면 중간에서 시작하는 부분에 선택적으로 밑줄을 적용 할 수 있음을 발견했습니다.

func underlinedString(string: NSString, term: NSString) -> NSAttributedString {
    let output = NSMutableAttributedString(string: string)
    let underlineRange = string.rangeOfString(term)
    output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleNone.rawValue, range: NSMakeRange(0, string.length))
    output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: underlineRange)

    return output
}

NSMutableAttributedString *signUpString = [[NSMutableAttributedString alloc] initWithString:@"Not a member yet?Sign Up now"];

[signUpString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]];

[signUpString addAttributes: @{NSForegroundColorAttributeName:UIColorFromRGB(0x43484B),NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:NSUnderlineStyleSingle]} range:NSMakeRange(17,11)];

signUpLbl.attributedText = [signUpString copy];

그것은 나를 위해 일했습니다


2018 년 9 월이므로이 답변은 iOS8에 관한 것이 아니지만 여전히 문자열의 일부에 밑줄을 긋는 것과 관련이 있습니다.

다음은 이미 구성된 용어 내에서 주어진 용어에 밑줄을 긋는 Swift 4 확장입니다.myAttributedString

extension NSMutableAttributedString {

    func underline(term: String) {

        guard let underlineRange = string.range(of: term) else {

            return
        }

        let startPosition = string.distance(from: term.startIndex, to: underlineRange.lowerBound)
        let nsrange = NSRange(location: startPosition, length: term.count)

        addAttribute(
            .underlineStyle,
            value: NSUnderlineStyle.styleSingle.rawValue,
            range: nsrange)
    }
}

용법: myAttributedString.underline(term: "some term")


반환 된 NSMutableAttributedString을 추가하여 @Joss의 답변의 Swift 5 버전 은 반환 된 NSMutableAttributedString 없이는 원래 솔루션을 사용할 수 없었기 때문입니다.

extension NSMutableAttributedString {

func underline(term: String) -> NSMutableAttributedString {
    guard let underlineRange = string.range(of: term) else {
        return NSMutableAttributedString()
    }
    let startPosition = string.distance(from: term.startIndex, to: underlineRange.lowerBound)
    let nsrange = NSRange(location: startPosition, length: term.count)
    addAttribute(
        .underlineStyle,
        value: NSUnderlineStyle.single.rawValue,
        range: nsrange)
     return self
}

}

용법:

 let myUnderLinedText = "Hello World"
 let underLinedMutableString =  NSMutableAttributedString(string: myUnderLinedText, attributes: titleAttributes).underline(term: myUnderLinedText)

I used the following extension (using exidy's function) in playground/simulator and it worked fine , you may change/add attributes depending on your needs

 extension NSMutableAttributedString
{


    func changeWordsColour(terms:[NSString])
{
    let string = self.string as NSString
    self.addAttribute(NSForegroundColorAttributeName, value: UIColor.brownColor(), range: NSMakeRange(0, self.length))
    for term in terms
    {
        let underlineRange = string.rangeOfString(term as String)
        self.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: underlineRange)

    }
}
}

 let myStr = NSMutableAttributedString(string: "Change Words Colour")
 myStr.changeWordsColour(["change","Colour"])

Add color for underline attribute:​​​

[attributedString addAttribute:NSUnderlineColorAttributeName
                     value:[UIColor redColor]
                     range:NSMakeRange(5, 6)];

참고URL : https://stackoverflow.com/questions/26136157/underline-part-of-a-string-using-nsmutableattributedstring-in-ios-8-is-not-worki

반응형