ios Swift制作字体切换粗体,斜体,boldItalic,正常而不改变其他属性
Posted
技术标签:
【中文标题】ios Swift制作字体切换粗体,斜体,boldItalic,正常而不改变其他属性【英文标题】:Ios Swift making font toggle bold, italic, boldItalic, normal without change other attributes 【发布时间】: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 中一样加粗。因为它试图创建一个供所有时间使用的通用对象 【参考方案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()
调用:
-
粗体字:
changeTrait(trait: .traitBold)
斜体: 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)
我不创建删除系统,因为我认为我们不需要它。 当我们创建字体时,我们建立了我们想要的样式,仅此而已。 希望我能帮上忙。
【讨论】:
以上是关于ios Swift制作字体切换粗体,斜体,boldItalic,正常而不改变其他属性的主要内容,如果未能解决你的问题,请参考以下文章
如何从字体面板(NSFontPanel)和颜色中仅检索字体样式(粗体,斜体,粗斜体)?
如何在 Android TextView 中将字体样式设置为粗体、斜体和下划线?
是否可以在 CSS `content` 中使用(多种)字体样式?