2017-12-06 20 views
6

Tôi có những điều sau đây cho phép tôi tạo danh sách dấu đầu dòng hoạt động thực sự tốt, tuy nhiên, sau khi danh sách dấu đầu dòng được tạo, tôi cần thao tác chuỗi được phân bổ đã xuất hoặc in đậm hoặc in nghiêng hoặc cả hai.Điều chỉnh các phần tử sau khi thao tác chuỗi thành AttributedString - Swift 4

Chức năng tôi có là:

@IBOutlet var label: UILabel! 
let bulletString = ["String 1","String 2","String 3"] 

label.attributedText = label.bulletPoints(stringList: bulletString, font: UIFont.stdFontMediumSeventeen, bullet: "•", lineSpacing: 4, paragraphSpacing: 4, textColor: UIColor.darkGreyColor, bulletColor: UIColor.darkGreyColor) 

func bulletPoints(stringList: [String],font: UIFont,bullet: String = "\u{2022}",indentation: CGFloat = 20,lineSpacing: CGFloat = 2,paragraphSpacing: CGFloat = 12,textColor: UIColor = .gray,bulletColor: UIColor = .red) -> NSAttributedString{ 
    let textAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: textColor] 
    let bulletAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: bulletColor] 

    let paragraphStyle = NSMutableParagraphStyle() 
    let nonOptions = [NSTextTab.OptionKey: Any]() 
    paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)] 
    paragraphStyle.defaultTabInterval = indentation 
    paragraphStyle.lineSpacing = lineSpacing 
    paragraphStyle.paragraphSpacing = paragraphSpacing 
    paragraphStyle.headIndent = indentation 

    let bulletList = NSMutableAttributedString() 
    for string in stringList { 
     let formattedString = "\(bullet)\t\(string)\n" 
     let attributedString = NSMutableAttributedString(string: formattedString) 

     attributedString.addAttributes(
      [NSAttributedStringKey.paragraphStyle : paragraphStyle], 
      range: NSMakeRange(0, attributedString.length)) 

     attributedString.addAttributes(
      textAttributes, 
      range: NSMakeRange(0, attributedString.length)) 

     let string:NSString = NSString(string: formattedString) 
     let rangeForBullet:NSRange = string.range(of: bullet) 
     attributedString.addAttributes(bulletAttributes, range: rangeForBullet) 
     bulletList.append(attributedString) 
    } 
    return bulletList 
} 

Những gì tôi đang tìm kiếm là một cách để vượt qua trong một boolean nêu nếu chuỗi đạn đòi hỏi một trong hai chữ in đậm hoặc in nghiêng và nếu như vậy những gì các yếu tố của chuỗi intital là cần điều trị này.

Chức năng bulletPoints nằm trong tệp mở rộng và hoạt động như mong đợi.

+0

Không rõ bạn đang cố gắng đạt được điều gì .. Bạn có muốn sửa đổi chuỗi được phân bổ hiện tại bằng cách áp dụng các thuộc tính mới không? Hoặc bạn muốn tham số mới trong hàm chịu trách nhiệm in đậm/in nghiêng? –

+0

Vì vậy, có, tôi đang tìm một hàm mà tôi có thể gọi trong hàm trên để đặt các phần nhất định của chuỗi thành chữ đậm hoặc in nghiêng hoặc cả hai, nhưng đối với hàm trên có thể sử dụng được mà không có các phần tử này. –

+0

Tôi không hiểu mục tiêu của bạn là gì. Làm thế nào để bạn biết nơi để áp dụng đậm/nghiêng (trong khác, nơi áp dụng một phông chữ mới)? Nếu nó nằm trên một mục của danh sách, giống như bạn đã làm 'attributedString.addAttributes ([NSAttributedStringKey.paragraphStyle: paragraphStyle], phạm vi: NSMakeRange (0, attributedString.length))' làm tương tự với 'NSAttributedStringKey.font' thay thế và một phông chữ tùy chỉnh. – Larme

Trả lời

1

Bạn có thể sử dụng nhiều phông chữ và văn bản. Nếu bạn biết phạm vi của văn bản mà bạn muốn áp dụng nhiều kiểu, bạn chỉ có thể sử dụng phông chữ. Kiểm tra ví dụ bên dưới.

let fullString = "Bold normal italic" 
let attrString = NSMutableAttributedString(string: fullString, attributes: [.font: UIFont.systemFont(ofSize: 18.0)]) 

let range1 = (fullString as NSString).range(of: "Bold") 
let range2 = (fullString as NSString).range(of: "italic") 
attrString.addAttributes([.font: UIFont.boldSystemFont(ofSize: 20.0)], range: range1) 
attrString.addAttributes([.font: UIFont.boldSystemFont(ofSize: 20.0).italics()], range: range2) 

label.attributedText = attrString 

Trong khi đó, tôi sử dụng phần mở rộng đơn giản cho UIFont.

extension UIFont { 
    func withTraits(_ traits: UIFontDescriptorSymbolicTraits) -> UIFont { 
     if let fd = fontDescriptor.withSymbolicTraits(traits) { 
      return UIFont(descriptor: fd, size: pointSize) 
     } 
     return self 
    } 

    func italics() -> UIFont { 
     return withTraits(.traitItalic) 
    } 
} 

Vì vậy, về cơ bản, những gì bạn cần biết là, mà văn bản được đánh dấu là nghiêng, đậm và bình thường. Sau đó, chỉ tính toán các phạm vi cho các văn bản đó trong văn bản gốc của bạn bằng cách sử dụng NSString.range (of:) và cập nhật các thuộc tính một cách thích hợp.

Lưu ý: Bạn cũng có thể tính phạm vi bằng cách sử dụng start và endIndex. Để tham khảo séc this SO answer. Hy vọng nó giúp. Chúc mừng mã hóa.

+0

Cảm ơn bạn có thể cung cấp một ví dụ theo chức năng của tôi và gọi cho câu hỏi của tôi –

0

Một trong những cách có thể để làm cho nó hoạt động với chức năng được đề cập trong câu hỏi - để sửa đổi thông số stringList.

Trước hết chúng ta hãy xác định mô hình lớp BulletString:

class BulletString { 
    var text: String 
    var attributes: [NSAttributedStringKey : Any]? 

    init(string: String) { 
     text = string 
    } 
} 

Bây giờ đạn của bạn stringList trong bạn hoạt động nên [BulletString] loại. Xác định hai bulletStrings và chuyển chúng vào hàm của bạn. Đây là một giải pháp làm việc với chức năng của bạn:

let bulletString1 = BulletString.init(string: "string1") 
    bulletString1.attributes = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 18.0)] 

    let bulletString2 = BulletString.init(string: "string2") 

    let bullets = [bulletString1, bulletString2] 

    label.attributedText = bulletPoints(stringList: bullets, font: UIFont.systemFont(ofSize: 17), bullet: "•", lineSpacing: 4, paragraphSpacing: 4, textColor: UIColor.darkGray, bulletColor: UIColor.darkGray) 
    label.textColor = .black 

func bulletPoints(stringList: [BulletString], font: UIFont,bullet: String = "\u{2022}",indentation: CGFloat = 20,lineSpacing: CGFloat = 2,paragraphSpacing: CGFloat = 12,textColor: UIColor = .gray,bulletColor: UIColor = .red) -> NSAttributedString{ 
    let textAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: textColor] 
    let bulletAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: bulletColor] 

    let paragraphStyle = NSMutableParagraphStyle() 
    let nonOptions = [NSTextTab.OptionKey: Any]() 
    paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)] 
    paragraphStyle.defaultTabInterval = indentation 
    paragraphStyle.lineSpacing = lineSpacing 
    paragraphStyle.paragraphSpacing = paragraphSpacing 
    paragraphStyle.headIndent = indentation 

    let bulletList = NSMutableAttributedString() 
    for bulletString in stringList { 
     let formattedString = "\(bullet)\t\(bulletString.text)\n" 
     let attributedString = NSMutableAttributedString(string: formattedString) 

     attributedString.addAttributes(
     [NSAttributedStringKey.paragraphStyle : paragraphStyle], 
     range: NSMakeRange(0, attributedString.length)) 

     attributedString.addAttributes(
     textAttributes, 
     range: NSMakeRange(0, attributedString.length)) 

     // Here your custom attributes you provided in BulletString 
     if let attr = bulletString.attributes { 
     attributedString.addAttributes(attr, range: NSMakeRange(0, attributedString.length)) 
     } 


     let string:NSString = NSString(string: formattedString) 
     let rangeForBullet:NSRange = string.range(of: bullet) 
     attributedString.addAttributes(bulletAttributes, range: rangeForBullet) 

     bulletList.append(attributedString) 
    } 
    return bulletList 
} 

Kết quả

enter image description here

4

Sử dụng một mô hình để liên kết các đậm/nghiêng vào chuỗi trong câu hỏi, như Neil gợi ý, giúp bạn trong trường hợp này. Đây là một phiên bản liên kết các đặc điểm phông chữ với các chuỗi cho mỗi dấu đầu dòng, sau đó sử dụng các ký tự đó khi tạo chuỗi.

Tôi cũng đã tái cấu trúc chức năng bulletPoints của bạn để loại bỏ việc sử dụng phạm vi và đơn giản hóa nó một chút. Nó có thể ở trong một phần mở rộng (tôi giả sử bạn có nó trên UILabel?) Nhưng không có lý do cho nó, vì nó trả về chuỗi anyway.Tôi đã viết nó như là một chức năng mà có thể được sử dụng trong bất kỳ lớp

class ViewController: UIViewController { 

    @IBOutlet var label: UILabel! 


    override func viewWillAppear(_ animated: Bool) { 
     let bulletStrings = [BulletString(string: "String 1", traits: []), 
          BulletString(string: "String 2", traits: [.traitBold]), 
          BulletString(string: "String 3", traits: [.traitItalic]), 
          BulletString(string: "String 4", traits: [.traitBold, .traitItalic])] 
     label.attributedText = bulletPoints(stringList: bulletStrings, font: UIFont.systemFont(ofSize: 15.0), bullet: "•", lineSpacing: 4, paragraphSpacing: 4, textColor: UIColor.darkGray, bulletColor: UIColor.darkGray) 

    } 

    func bulletPoints(stringList: [BulletString], 
         font: UIFont, 
         bullet: String = "\u{2022}", 
         indentation: CGFloat = 20, 
         lineSpacing: CGFloat = 2, 
         paragraphSpacing: CGFloat = 12, 
         textColor: UIColor = .gray, 
         bulletColor: UIColor = .red) -> NSAttributedString { 

     let bulletList = NSMutableAttributedString() 
     for bulletString in stringList { 
      let attributedString = NSMutableAttributedString(string: "") 
      let bulletAttributes: [NSAttributedStringKey: Any] = [ 
       .foregroundColor: bulletColor, 
       .font: font] 
      attributedString.append(NSAttributedString(string: bullet, attributes: bulletAttributes)) 

      let textAttributes: [NSAttributedStringKey: Any] = [ 
       .font: font.withTraits(traits: bulletString.traits), 
       .foregroundColor: textColor, 
       .paragraphStyle : paragraphStyle(indentation: indentation, lineSpacing: lineSpacing, paragraphSpacing: paragraphSpacing) 
      ] 
      attributedString.append(NSAttributedString(string:"\t\(bulletString.string)\n", attributes: textAttributes)) 

      bulletList.append(attributedString) 
     } 
     return bulletList 
    } 

    private func paragraphStyle(indentation: CGFloat, lineSpacing: CGFloat, paragraphSpacing: CGFloat) -> NSParagraphStyle { 
     let style = NSMutableParagraphStyle() 
     let nonOptions = [NSTextTab.OptionKey: Any]() 
     style.tabStops = [NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)] 
     style.defaultTabInterval = indentation 
     style.lineSpacing = lineSpacing 
     style.paragraphSpacing = paragraphSpacing 
     style.headIndent = indentation 
     return style 
    } 
} 

struct BulletString { 
    let string: String 
    let traits: UIFontDescriptorSymbolicTraits 
} 

extension UIFont { 

    func withTraits(traits:UIFontDescriptorSymbolicTraits...) -> UIFont { 
     let descriptor = self.fontDescriptor 
      .withSymbolicTraits(UIFontDescriptorSymbolicTraits(traits))! 
     return UIFont(descriptor: descriptor, size: 0) 
    } 

} 

Results of example

Nếu bạn muốn có đạn phù hợp với phong cách của chuỗi của họ, tức là được in đậm hoặc in nghiêng, bạn có thể chỉ thêm các thuộc tính trong một lần truyền cho mỗi viên đạn

Các vấn đề liên quan