Ios Swift позволяет переключать шрифты полужирный, курсив, жирный курсив, обычный без изменения других атрибутов

Я удивлен, что просто установить полужирный шрифт и курсив для существующего шрифта так сложно в Swift.

Я просто хочу упростить ситуацию, используя следующие методы для класса шрифта.

Я хочу, чтобы приведенные ниже методы были добавлены к существующему шрифту, для которого установлено семейство шрифтов и размер шрифта. Мне нужно сохранить их и изменить только следующее.

setBold : Сохраняйте курсив

setItalic : Сохраняйте полужирный шрифт

setBoldItalic

setNormal : удалить как полужирный, так и курсив

removeBold : Сохраняйте курсив

removeitalic : держи жирным шрифтом

Я попробовал следующее, и для меня это похоже на кошмар, используя 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)

Я искал везде и не нашел простого решения, соответствующего моим потребностям.


person Sujay U N    schedule 22.07.2016    source источник
comment
Я думаю, очень важно проверить семейство шрифтов, потому что не все из них имеют жирный шрифт и курсив, вы используете шрифты по умолчанию или добавили новый?   -  person reojased    schedule 22.07.2016
comment
У меня есть собственный список семейства шрифтов, в котором есть полужирный шрифт и курсив. Также Text Color также присутствует вместе со шрифтом   -  person Sujay U N    schedule 22.07.2016
comment
большинство шрифтов имеют суффикс Bold или Italic, поэтому, если ваши имена шрифтов соответствуют этому шаблону, возможно, вы создадите свои шрифты по их именам.   -  person Ali Kıran    schedule 22.07.2016
comment
Мои методы не должны зависеть от семейства шрифтов, они должны быть выделены жирным шрифтом, как в css. Потому что я пытаюсь создать общий на все времена.   -  person Sujay U N    schedule 22.07.2016


Ответы (6)


Вы говорите, что хотите сохранить другие черты, поэтому вам может потребоваться изменить некоторые методы в вашем коде:

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(). Вы хотите удалить все черты или просто удалить курсив и жирный шрифт? Может быть, вы можете сделать это сами, как вам нравится.

person OOPer    schedule 22.07.2016
comment
Это то, что я искал, большое спасибо. Вы действительно спасли мой день :-) - person Sujay U N; 23.07.2016
comment
@ReimondHill, объясните, пожалуйста, не работает. Насколько я тестирую свой код с Xcode 10 и iPhone sim 12.0, мой код, переведенный для Swift 4.2, работает, как и ожидалось. - person OOPer; 27.10.2018

Эти функции должны были быть встроены в Swift, но я бы хотел, чтобы они были добавлены в следующих версиях.

Это для всех, кто хочет простое решение для выделения жирным шрифтом и курсивом... и т. д. в Swift и не хочет провести всю ночь, как я.

Это имеет следующие особенности:

полужирный

курсив

setBold: следует сохранить курсив

setItalic: следует сохранить жирный шрифт

setBoldItalic

setNormal: удалить как полужирный, так и курсив

desetBold: следует сохранить курсив

desetItalic: следует сохранить полужирный шрифт

переключить полужирный

toggleКурсив

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()
        }
    }
}
person Sujay U N    schedule 22.07.2016

Свифт 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)
    }
}
}
person Saleh Altahini    schedule 04.07.2017

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)
person aashish tamsya    schedule 07.06.2017

Другой способ сделать это — проверить выделение жирным и курсивом кнопок.

Для жирного шрифта:

@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)
}

}
person Himani C.    schedule 02.09.2020

Я не знаю, смогу ли я вам помочь, но я думаю, что вы можете сделать это следующим образом:

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)
    }
}

Я не создаю систему удаления, потому что не думаю, что она нам понадобится. Когда мы создаем шрифт, мы устанавливаем нужные стили, и все. Надеюсь, я помог.

person Foxynh    schedule 18.04.2019