1

I have a custom font that I'm using in my app, Cassandra-Personal. It's a signature style font. Whenever I use it inside of a Text("someText") the font is clipped on the top and bottom due to ascenders and descenders present in the font. A couple of fixes that I've attempted are to change the .frame(), .baselineOffset(), and I also attempted to play around with the kerning/tracking to no avail. In short the text, regardless of the frame, is clipped. Whenever I .baselineOffset() it fixes the one side or the other, but not both sides. For obvious reasons I can't offset both sides simultaneously.

The View

struct GroupListHeaderView: View {
    let headerTitle: String
    var body: some View {
        ZStack(alignment: .center) {
            Rectangle().fill(Color(UIColor.yellow))
            Text(headerTitle)
                .font(Fonts.header)
                .frame(height: 100)
                
        }.frame(height: 100)
    }
}

Addt'l Supplementary Code

struct Fonts {
    // Other fonts removed, not relevant.
    static let header = Font.custom(FontName.cassandra.rawValue, size: 30)
}

public enum FontName: String {
    // Other cases removed, not relevant.
    case cassandra = "CassandraPersonalUse-Regular"
}

Example #1

  • Baseline Offset of 30

enter image description here

Example #2

  • Baseline Offset of -30

enter image description here

Example #3

  • Frame height: 100

enter image description here

xTwisteDx
  • 2,152
  • 1
  • 9
  • 25
  • (Kerning and Tracking change the horizontal spacing between characters). Did you create the font, or did you just get it from somewhere else? – Scott Thompson Oct 28 '21 at 20:43
  • @ScottThompson it's a font that I downloaded. I didn't create it. I have used the same font in UIKit based applications without issue. – xTwisteDx Oct 28 '21 at 20:45
  • It's hard to say if `Text` is clipping to the line height, or to the ascent and descent of the font. There's no hard rule that a font set its Ascent and Descent properly to fit the glyphs (this certainly would not be the first font I've seen that was "wrong") but its weird that `Text` is clipping at all since most views use their frames for layout, but let drawing extend farther (unless you use `.clipped`). If you let the text go long, does it extend beyond the frame? What if you use something like the Zapfino font - which has wild ascenders and descenders... are they clipped too? – Scott Thompson Oct 28 '21 at 21:00
  • Also... (I know - lots of comments) have you tried changing the `lineSpacing` (an environment attribute) or changing the leading on the `header` font object? I'm grasping at straws trying to decide what values `Text` might be using to set its clip. – Scott Thompson Oct 28 '21 at 21:06
  • Here is a solution which helped me when dealing with a music score font in SwiftUI quite a lot. The issue I meet was exactly same with you. https://stackoverflow.com/questions/44374358/system-font-hiragino-sans-is-show-with-clipped-ascender-and-descenders/59710785#59710785 – Mekal Sep 09 '22 at 14:41

2 Answers2

0

I faced with this problem today.

I have a workaround, but this is not the final solution. I add an invisible character '|' before and after the string.

func titleLabel(of title: String, fontName: String, fontSize: CGFloat, textColor: UIColor) -> AttributedString {
    let result = NSMutableAttributedString()

    var beginAttributes: [NSAttributedString.Key: Any] = [:]
    beginAttributes[.font] = UIFont(name: fontName, size: fontSize)
    beginAttributes[.foregroundColor] = UIColor.clear
    beginAttributes[.baselineOffset] = -fontSize  / 4
    let beginAttributedString = NSAttributedString(string: "|", attributes: beginAttributes)
    result.append(beginAttributedString)

    var mainAttributes: [NSAttributedString.Key: Any] = [:]
    mainAttributes[.font] = UIFont(name: fontName, size: fontSize)
    mainAttributes[.foregroundColor] = textColor
    let mainAttributedString = NSAttributedString(string: title, attributes: mainAttributes)
    result.append(mainAttributedString)

    var endAttributes: [NSAttributedString.Key: Any] = [:]
    endAttributes[.font] = UIFont(name: fontName, size: fontSize)
    endAttributes[.foregroundColor] = UIColor.clear
    endAttributes[.baselineOffset] = fontSize  / 4
    let endAttributedString = NSAttributedString(string: "|", attributes: endAttributes)
    result.append(endAttributedString)

    let string = AttributedString(result)
    return string
}
// useage:
Text(self.titleLabel(of: "Some Title", fontName: "CassandraPersonalUse-Regular", fontSize: 30, textColor: .black))
feca
  • 1,119
  • 16
  • 14
-1

This down code should solve your issue:

Note: You can not give a fixed size to ZStack! because it would overridden the needed size for Text! it may get big or small size!

Also I think you would need use backgroundColor for Text instead of using Rectangle().

struct GroupListHeaderView: View {
    
    let headerTitle: String
    
    var body: some View {
        
        Rectangle().fill(Color(UIColor.yellow))
            .overlay(Text(headerTitle).font(Font.custom("CassandraPersonalUse-Regular", size: 30)))
        
    }
}
ios coder
  • 1
  • 4
  • 31
  • 91
  • That does not fix it. Same issue. – xTwisteDx Oct 28 '21 at 20:44
  • Then try just this code: `Text(headerTitle).font(Font.custom("CassandraPersonalUse-Regular", size: 30)).background(Color.yellow)` – ios coder Oct 28 '21 at 20:46
  • Negative. Same issue. I'm thinking I need to change the font if there's no clear solution. – xTwisteDx Oct 28 '21 at 20:47
  • I can guess what is happening! I also made some custom Font for myself! It could be get messed up due to xCode versions! For example I had fully working Font in one version, after update i got same issues, then i fixed the font for new update! and then it got issue in new update for xcode! – ios coder Oct 28 '21 at 20:49
  • What can I adjust on the font to correct it? – xTwisteDx Oct 28 '21 at 20:56
  • I cannot give the last answer, may the font itself has issue! – ios coder Oct 28 '21 at 21:45