【问题标题】:How to make a bullet list with Swift?如何使用 Swift 制作项目符号列表?
【发布时间】:2017-08-22 08:15:12
【问题描述】:

所以我想用 swift 和 xcode 做这样的事情:

我从数组中获取每个点。我的想法是制作一个 UILabel 并制作一个迭代数组的 for 循环,并在每次迭代中添加到标签 \u{2022} + 内容中。我知道 \u{2022} 是 unicode 中的点,问题是我需要一种方法将列表分成两列,如图所示,并使点颜色为黄色。如果我如上所述以编程方式添加点,则无法完成此操作,因为默认颜色将为黑色。由于点的数量因数组内容而异,例如,如果数组的大小为 3,那么只有 3 个点会在左侧显示 2,在右侧显示一个我需要一种方法来满足这个要求,我认为的另一种方法是有两个占屏幕一半的表格视图,并根据数组将此元素添加到每个表格视图中。这里的最佳实践应该是什么,或者有没有办法以依赖于数组的形式在情节提要中做到这一点。

【问题讨论】:

标签: ios swift swift3


【解决方案1】:

在视图中为列使用 2 个标签。两个标签都被复用了

class Helper {

    static func bulletedList(strings:[String], textColor:UIColor, font:UIFont, bulletColor:UIColor, bulletSize:BulletSize) -> NSAttributedString {
        let textAttributesDictionary = [NSFontAttributeName : font, NSForegroundColorAttributeName:textColor]

        let bulletAttributesDictionary = [NSFontAttributeName : font.withSize(bulletSize.rawValue), NSForegroundColorAttributeName:bulletColor]
        let fullAttributedString = NSMutableAttributedString.init()

        for string: String in strings
        {
            let bulletPoint: String = "\u{2022}"
            let formattedString: String = "\(bulletPoint) \(string)\n"
            let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: formattedString)
            let paragraphStyle = createParagraphAttribute()

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

            let string:NSString = NSString(string: formattedString)
            let rangeForBullet:NSRange = string.range(of: bulletPoint)

            attributedString.addAttributes(bulletAttributesDictionary, range: rangeForBullet)
            fullAttributedString.append(attributedString)
        }
        return fullAttributedString
    }

    static func createParagraphAttribute() -> NSParagraphStyle {

        var paragraphStyle: NSMutableParagraphStyle
        paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
        paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: 15, options: NSDictionary() as! [String : AnyObject])]
        paragraphStyle.defaultTabInterval = 15
        paragraphStyle.firstLineHeadIndent = 0
        paragraphStyle.lineSpacing = 3
        paragraphStyle.headIndent = 10
        return paragraphStyle
    }
}

只需使用Helper.bulletedList 将项目符号列表创建为标签的属性文本

【讨论】:

    【解决方案2】:

    在 Swift 中,tabStop 将适用于以下更改

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.minimumLineHeight = 0 // 0 means unlimited
    paragraphStyle.maximumLineHeight = 0
    paragraphStyle.firstLineHeadIndent = 30
    paragraphStyle.headIndent = 0
    paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: 15, options: Dictionary<NSTextTab.OptionKey, Any>())]
    paragraphStyle.defaultTabInterval = 10  //changing defaultTabInterval changes the distance between black dot & text
    paragraphStyle.lineSpacing = 5
    

    【讨论】:

      【解决方案3】:

      对于 Swift 5,你可以使用这个类:

      class NSAttributedStringHelper {
          static func createBulletedList(fromStringArray strings: [String], font: UIFont? = nil) -> NSAttributedString {
      
              let fullAttributedString = NSMutableAttributedString()
              let attributesDictionary: [NSAttributedString.Key: Any]
          
              if let font = font {
                  attributesDictionary = [NSAttributedString.Key.font: font]
              } else {
                  attributesDictionary = [NSAttributedString.Key: Any]()
              }
         
              for index in 0..<strings.count {
                  let bulletPoint: String = "\u{2022}"
                  var formattedString: String = "\(bulletPoint) \(strings[index])"
              
                  if index < strings.count - 1 {
                      formattedString = "\(formattedString)\n"
                  }
              
                  let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: formattedString, attributes: attributesDictionary)
                  let paragraphStyle = NSAttributedStringHelper.createParagraphAttribute()
         attributedString.addAttributes([NSAttributedString.Key.paragraphStyle: paragraphStyle], range: NSMakeRange(0, attributedString.length))
              fullAttributedString.append(attributedString)
             }
          
              return fullAttributedString
          }
      
          private static func createParagraphAttribute() -> NSParagraphStyle {
              let paragraphStyle: NSMutableParagraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
              paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: 15, options: NSDictionary() as! [NSTextTab.OptionKey : Any])]
              paragraphStyle.defaultTabInterval = 15
              paragraphStyle.firstLineHeadIndent = 0
              paragraphStyle.headIndent = 11
              return paragraphStyle
          }
      }
      

      使用它:

      let stringArray = ["first row", "second row", "third row"]
      label.attributedText = NSAttributedStringHelper.createBulletedList(fromStringArray: stringArray, font: UIFont.systemFont(ofSize: 15))
      

      【讨论】:

      • 这个解决方案非常完美。无需太多努力,它就可以像在任何好看的文档中一样输出项目符号列表。感谢您分享此代码。
      • 感谢这个很酷的 sn-p,一个问题,你怎么能把所有的价值放在中心?我尝试将您的帮助程序类中的文本对齐到中心,但它不起作用,而且我的故事板对齐已经设置在中心。
      • 感谢您的解决方案。但是,可以避免在定义制表位时施加的力。 [NSTextTab(textAlignment: .left, location: 15, options: [NSTextTab.OptionKey: Any]())] 另外,我们可以在添加属性时使用 NSRange 而不是 NSMakeRange。 NSRange(location: 0, length: attributedString.length)
      【解决方案4】:

      我对上述解决方案不满意。所以这里有一个 Swifty 函数来获取项目符号列表:

      func bulletPointList(strings: [String]) -> NSAttributedString {
          let paragraphStyle = NSMutableParagraphStyle()
          paragraphStyle.headIndent = 15
          paragraphStyle.minimumLineHeight = 22
          paragraphStyle.maximumLineHeight = 22
          paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: 15)]
      
          let stringAttributes = [
              NSAttributedString.Key.font: regularSystem(size: 22),
              NSAttributedString.Key.foregroundColor: UIColor.black,
              NSAttributedString.Key.paragraphStyle: paragraphStyle
          ]
      
          let string = strings.map({ "•\t\($0)" }).joined(separator: "\n")
      
          return NSAttributedString(string: string,
                                    attributes: stringAttributes)
      }
      

      这就是你使用它的方式:

      label.numberOfLines = 0
      label.attributedText = bulletPointList(strings: ["Foo", "Bar", "Lol"])
      

      【讨论】:

      • 这对列表有好处,而不会更改项目符号颜色。所以它与文本具有相同的颜色,我正在寻找这种特殊的样式,否则我可以将项目符号放在文本中。并保持简单。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      相关资源
      最近更新 更多