【问题标题】:Ios Swift making font toggle bold, italic, boldItalic, normal without change other attributesios Swift制作字体切换粗体,斜体,boldItalic,正常而不改变其他属性
【发布时间】:2016-07-22 18:41:02
【问题描述】:

我很惊讶,在 Swift 中简单地为现有字体设置粗体和斜体是如此复杂。

我只是想通过在字体类上使用以下方法来简化事情。

我希望将以下方法添加到已设置 font-family 和 font-size 的现有字体中。我需要保留这些并仅更改以下内容。

setBold : Shud 保留斜体

setItalic : Shud 保留粗体

setBoldItalic

setNormal : 去掉粗体和斜体

removeBold : Shud 保留斜体

removeitalic : Shud 保留粗体

我尝试了以下方法,但使用 fontDescriptorWithSymbolicTraits 对我来说就像一场噩梦。

有没有更简单的方法可以在几行代码中完成这些操作?

extension UIFont
{
    var isBold: Bool
    {
        return fontDescriptor().symbolicTraits.contains(.TraitBold)
    }

    var isItalic: Bool
    {
        return fontDescriptor().symbolicTraits.contains(.TraitItalic)
    }

    func setBold() -> UIFont
    {
        var fontDescriptorVar: UIFontDescriptor
        if(isBold){
            return self
        }
        else
        {
            fontDescriptorVar = fontDescriptor().fontDescriptorWithSymbolicTraits(.TraitBold)
        }
        return UIFont(descriptor: fontDescriptorVar, size: 0)
    }

    func setItalic()-> UIFont
    {
        var fontDescriptorVar: UIFontDescriptor
        if(isItalic) {
            return self
        }
        else
        {
            fontDescriptorVar = fontDescriptor().fontDescriptorWithSymbolicTraits(.TraitItalic)
        }
        return UIFont(descriptor: fontDescriptorVar, size: 0)
    }

    func setBoldItalic()-> UIFont
    {
        let fontDescriptorVar = fontDescriptor().fontDescriptorWithSymbolicTraits(UIFontDescriptorSymbolicTraits(arrayLiteral: .TraitBold, .TraitItalic))
        return UIFont(descriptor: fontDescriptorVar, size: 0)
    }

    // Things I need are

    // To set back to normal

    func setNormal()-> UIFont
    {

    }

    // Remove only bold if it's both bold and Italic

    func removeBold()-> UIFont
    {

    }

    // Remove only italic if it's both bold and Italic

    func removeitalic()-> UIFont
    {

    }
}

我不想使用这个询问我输入的大小和字体:

UIFont(name "namFontFamily", size: 16)

UIFont.systemFontOfSize(16, weight: UIFontWeightLight)

我到处搜索,没有找到符合我需求的简单解决方案。

【问题讨论】:

  • 我认为检查字体系列非常重要,因为并非所有字体都有粗体和斜体形式,您是使用默认字体还是添加了新字体?
  • 我有自己的字体系列列表,其中包括粗体和斜体。字体也有文本颜色
  • 大多数字体都有“粗体”或“斜体”后缀,所以如果您的字体名称与此模式匹配,您可能会根据它们的名称来构建您的字体。
  • 我的方法应该与字体系列无关,它应该像在 css 中一样加粗。因为它试图创建一个供所有时间使用的通用对象

标签: ios swift uifont bold italic


【解决方案1】:

您说要保留其他特征,因此您可能需要修改代码中的某些方法:

func setBold() -> UIFont
{
    if isBold {
        return self
    } else {
        var symTraits = fontDescriptor().symbolicTraits
        symTraits.insert([.TraitBold])
        let fontDescriptorVar = fontDescriptor().fontDescriptorWithSymbolicTraits(symTraits)
        return UIFont(descriptor: fontDescriptorVar, size: 0)
    }
}

setItalic()setBoldItalic() 也是如此。

所以,removeBold() 应该是这样的:

func removeBold()-> UIFont
{
    if !isBold {
        return self
    } else {
        var symTraits = fontDescriptor().symbolicTraits
        symTraits.remove([.TraitBold])
        let fontDescriptorVar = fontDescriptor().fontDescriptorWithSymbolicTraits(symTraits)
        return UIFont(descriptor: fontDescriptorVar, size: 0)
    }
}

removeItalic() 类似。

但我不确定setNormal()。您想删除所有特征,还是只想删除斜体和粗体?也许你可以随心所欲地自己做。

【讨论】:

  • 这是我一直在寻找的,非常感谢。你真的拯救了我的一天:-)
  • @ReimondHill,请解释一下不起作用。就我使用 Xcode 10 和 iPhone sim 12.0 测试我的代码而言,我为 Swift 4.2 翻译的代码按预期工作。
【解决方案2】:

这些函数本应内置在 Swift 中,但我希望他们在即将发布的版本中添加它们。

这适用于所有想要在 Swift 中设置粗体和斜体...等的简单解决方案并且不想像我一样度过整个晚上的人。

它具有以下特点:

粗体

是斜体

setBold: 应该保留斜体

setItalic:应该保留粗体

setBoldItalic

setNormal:去掉粗体和斜体

desetBold:应该保留斜体

desetItalic:应该保留粗体

切换粗体

切换斜体

extension UIFont
{
    var isBold: Bool
    {
        return fontDescriptor().symbolicTraits.contains(.TraitBold)
    }

    var isItalic: Bool
    {
        return fontDescriptor().symbolicTraits.contains(.TraitItalic)
    }

    func setBoldFnc() -> UIFont
    {
        if(isBold)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor().symbolicTraits
            fontAtrAry.insert([.TraitBold])
            let fontAtrDetails = fontDescriptor().fontDescriptorWithSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails, size: 0)
        }
    }

    func setItalicFnc()-> UIFont
    {
        if(isItalic)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor().symbolicTraits
            fontAtrAry.insert([.TraitItalic])
            let fontAtrDetails = fontDescriptor().fontDescriptorWithSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails, size: 0)
        }
    }

    func setBoldItalicFnc()-> UIFont
    {
        return setBoldFnc().setItalicFnc()
    }

    func detBoldFnc() -> UIFont
    {
        if(!isBold)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor().symbolicTraits
            fontAtrAry.remove([.TraitBold])
            let fontAtrDetails = fontDescriptor().fontDescriptorWithSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails, size: 0)
        }
    }

    func detItalicFnc()-> UIFont
    {
        if(!isItalic)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor().symbolicTraits
            fontAtrAry.remove([.TraitItalic])
            let fontAtrDetails = fontDescriptor().fontDescriptorWithSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails, size: 0)
        }
    }

    func SetNormalFnc()-> UIFont
    {
        return detbBoldFnc().detbItalicFnc()
    }

    func toggleBoldFnc()-> UIFont
    {
        if(isBold)
        {
            return detbBoldFnc()
        }
        else
        {
            return setBoldFnc()
        }
    }

    func toggleItalicFnc()-> UIFont
    {
        if(isItalic)
        {
            return detbItalicFnc()
        }
        else
        {
            return setItalicFnc()
        }
    }
}

【讨论】:

    【解决方案3】:

    斯威夫特 3.1

    extension UIFont{
    var isBold: Bool
    {
        return fontDescriptor.symbolicTraits.contains(.traitBold)
    }
    
    var isItalic: Bool
    {
        return fontDescriptor.symbolicTraits.contains(.traitItalic)
    }
    
    func setBold() -> UIFont
    {
        if(isBold)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor.symbolicTraits
            fontAtrAry.insert([.traitBold])
            let fontAtrDetails = fontDescriptor.withSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails!, size: pointSize)
        }
    }
    
    func setItalic()-> UIFont
    {
        if(isItalic)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor.symbolicTraits
            fontAtrAry.insert([.traitItalic])
            let fontAtrDetails = fontDescriptor.withSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails!, size: pointSize)
        }
    }
    func desetBold() -> UIFont
    {
        if(!isBold)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor.symbolicTraits
            fontAtrAry.remove([.traitBold])
            let fontAtrDetails = fontDescriptor.withSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails!, size: pointSize)
        }
    }
    
    func desetItalic()-> UIFont
    {
        if(!isItalic)
        {
            return self
        }
        else
        {
            var fontAtrAry = fontDescriptor.symbolicTraits
            fontAtrAry.remove([.traitItalic])
            let fontAtrDetails = fontDescriptor.withSymbolicTraits(fontAtrAry)
            return UIFont(descriptor: fontAtrDetails!, size: pointSize)
        }
    }
    }
    

    【讨论】:

      【解决方案4】:

      SWIFT 3.1

      func changeTrait(trait: UIFontDescriptorSymbolicTraits) {
              let range = textView.selectedRange
              let currentAttributes = textView.textStorage.attributes(at: range.location, effectiveRange: nil)
              guard let currentFont = currentAttributes[NSFontAttributeName] as? UIFont else {
                  return
              }
      
              let fontDescriptor = currentFont.fontDescriptor
              var changedFontDescriptor: UIFontDescriptor!
      
      
              if fontDescriptor.symbolicTraits.contains(trait) {
                  let existingTraitsWithNewTrait = UIFontDescriptorSymbolicTraits(rawValue: fontDescriptor.symbolicTraits.rawValue & ~trait.rawValue)
                  changedFontDescriptor = fontDescriptor.withSymbolicTraits(existingTraitsWithNewTrait)
              } else {
                  changedFontDescriptor = fontDescriptor.withSymbolicTraits(UIFontDescriptorSymbolicTraits(rawValue: fontDescriptor.symbolicTraits.rawValue | trait.rawValue))
              }
      
              let updatedFont = UIFont(descriptor: changedFontDescriptor , size: 0)
      
              let newAttributes = [NSFontAttributeName: updatedFont]
              textView.textStorage.beginEditing()
              textView.textStorage.setAttributes(newAttributes, range: range)
              textView.textStorage.endEditing()
       }
      

      调用:

      1. 粗体字: changeTrait(trait: .traitBold)
      2. 斜体: changeTrait(trait: .traitItalic)

      【讨论】:

        【解决方案5】:

        另一种方法是检查粗体和斜体按钮的选择

        粗体:

        @IBAction func bold(_ sender : UIButton){
            sender.isSelected = !sender.isSelected
            if sender.isSelected{
                self.textView.font = self.textView.font?.bold()
            }else{
                self.textView.font = self.textView.font?.removeBold()
            }
        }
        

        斜体:

        @IBAction func italic(_ sender : UIButton){
            sender.isSelected = !sender.isSelected
            if sender.isSelected{
                self.textView.font = self.textView.font?.italic()
            }else{
                self.textView.font = self.textView.font?.removeItalic()
            }
        }
        

        那么 UIFont 扩展可以容纳不同的方法来添加和删除特征

        确保在 withTraits 方法中添加新特征时保留以前的特征

        extension UIFont {
        
        //Add Traits
        func withTraits(traits:UIFontDescriptor.SymbolicTraits) -> UIFont {
            let symTraits = fontDescriptor.symbolicTraits
            let descriptor = fontDescriptor.withSymbolicTraits(UIFontDescriptor.SymbolicTraits(arrayLiteral: symTraits, traits))
            return UIFont(descriptor: descriptor!, size: 0) //size 0 means keep the size as it is
        }
        
        func bold() -> UIFont {
            return withTraits(traits: .traitBold)
        }
        
        func italic() -> UIFont {
            return withTraits(traits: .traitItalic)
        }
        
        //remove traits
        func withoutTraits(traits:UIFontDescriptor.SymbolicTraits) -> UIFont {
            var symTraits = fontDescriptor.symbolicTraits
            symTraits.remove([traits])
            let fontDescriptorVar = fontDescriptor.withSymbolicTraits(symTraits)
            return UIFont(descriptor: fontDescriptorVar!, size: 0)
        }
        
        func removeBold() -> UIFont {
            return withoutTraits(traits: .traitBold)
        }
        
        func removeItalic() -> UIFont {
            return withoutTraits(traits: .traitItalic)
        }
        
        }
        

        【讨论】:

          【解决方案6】:

          我不知道我是否可以帮助你,但我认为你可以这样做:

          extension UIFont {
          
              public static func CreateWithStyle(name: String, size: CGFloat, styles: [UIFontDescriptor.SymbolicTraits]) -> UIFont {
          
                  let fontDescriptor = UIFontDescriptor(name: name, size: size)
                  var fontAtrAry = fontDescriptor.symbolicTraits
          
                  if styles.count > 0 {
          
                      for style in styles {
                          fontAtrAry.update(with: style)
                      }
                  }
          
                  return UIFont(descriptor: fontDescriptor.withSymbolicTraits(fontAtrAry)!, size: size)
              }
          }
          

          我不创建删除系统,因为我认为我们不需要它。 当我们创建字体时,我们建立了我们想要的样式,仅此而已。 希望我能帮上忙。

          【讨论】:

            猜你喜欢
            • 2013-12-03
            • 1970-01-01
            • 1970-01-01
            • 2011-07-18
            • 2015-07-23
            • 1970-01-01
            • 2014-02-13
            • 2019-07-20
            • 1970-01-01
            相关资源
            最近更新 更多