SwiftCoderJr
SwiftCoderJr

Reputation: 23

Text on SwiftUI getting cut off on trailing side, any solutions?

I'm having a problem with custom Font in SwiftUI, I'm use Google Fonts Allura,Courgette,Mr Dafoe, Shoadows Into Light Two, and Source Sans Pro. I provided image below of example you can its cutting the character either from the back or the front and only doing them to characters with height, like D,H,J,I and etc.

enter image description here enter image description here

I've tried giving it a frame with .infinity and adjusting the height. I've also tried adding padding and padding(trailing). Furthermore, I've attempted using .fixedSize(horizontal: true, vertical: false) and .scaledToFit(), but none of these methods have worked. I suspected there might be an issue with my view, so I created an entirely new project in SwiftUI, gave Text("Hello World!") a custom font, and encountered the same issue.

Then, while searching, I found a custom UIKit label, which worked when I tried it. It seems that when the custom font is applied as a UIFont, it works perfectly, but when it's used as a SwiftUI.Font, it does not.

I've even tried integrating the custom UIKit label into my code, but the problem persists. I need the label to resize and change the font size dynamically as the number of characters increases, to fit on one line and within the view's width. Below is the SwiftUI code as the Minimum Deployment is iOS 15 just for aheads up.


                HStack(spacing: 8) {
                    Spacer()
                    Text(signText)
                        .lineLimit(1)
                        .allowsTightening(true)
                        .minimumScaleFactor(0.5 / 2)
                        .font(font)

                        .frame(maxWidth: .infinity,idealHeight: 150, alignment: .center)
                    
                    Spacer()
                    if !signText.isEmpty {
                        Button(action: {
                            isSignSheetPresented = true
                        }, label: {
                            Image("edit")
                                .renderingMode(.template)
                                .frame(idealWidth: 44)
                                .foregroundColor(Color(CanopyColor.primary.color))
                        })
                    }
                }
                .padding(16)
                .frame(maxWidth: .infinity, idealHeight: 150, alignment: .center )
                .background(Color(red: 0.98, green: 0.98, blue: 0.98)) // Color Change
                .cornerRadius(4)
                .overlay(
                  RoundedRectangle(cornerRadius: 4)
                    .inset(by: 0.5)
                    .stroke(Color(red: 0.87, green: 0.87, blue: 0.87), lineWidth: 1) 
                )

This is the UILabel that I used

struct UILabelView: UIViewRepresentable {
    var text: String
    var font: UIFont
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.font = font
        label.text = text
        label.numberOfLines = 1
        label.textAlignment = .center
        label.backgroundColor = .clear
        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.25
        label.allowsDefaultTighteningForTruncation = true
        label.translatesAutoresizingMaskIntoConstraints = false
        label.widthAnchor.constraint(equalToConstant: 100).isActive = true
        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.text = text
        uiView.font = font
        uiView.textAlignment = .center
    }
}

If there anymore question or information that I've missed please Comment so I can add them.

Also all the font I mentioned above are from Google Fonts here are the name of them in code so it easier to find.

Allura-Regular Courgette-Regular MrDafoe-Regular ShadowsIntoLightTwo-Regular SourceSansPro-Regular

Upvotes: 2

Views: 772

Answers (1)

Jack Goossen
Jack Goossen

Reputation: 1271

I believe this to be a bug in iOS font rendering and have accepted it as such in my own app. The only workaround I found is adding padding spaces to your string. You can adjust the font of the padding whitespace, so that the padding has a fixed width (independent of the font used for the rest of the string). You can then compensate for the padding if needed.

struct ContentView: View {
    
    let font = Font.custom("Allura-Regular", size: 32)
    
    // create an attributed string with fixed width padding
    var attributedString: AttributedString {
        var padding = AttributedString(" ")
        padding.font = .monospacedSystemFont(ofSize: 32, weight: .regular)
        
        var text = AttributedString("Assasin's Creed")
        text.font = font
        
        var result = padding
        result.append(text)
        result.append(padding)
        return result
    }
    
    var body: some View {
        // create a container with leading alignment to demonstrate compensating
        // for the padding
        ZStack(alignment: .leading) {
            Color.clear
            
            Text(attributedString)
                .lineLimit(1)
                .fixedSize()
                .offset(x: -20) // measured fixed width of the padding space
                                // (measured with GeometryReader)
        }
    }
}

Alternatively you can also concatenate Text instead of using an attributed string.

    let paddingFont = Font.system(size: 32).monospaced()
    
    var body: some View {
        // create a container with leading alignment to demonstrate compensating
        // for the padding
        ZStack(alignment: .leading) {
            Color.clear
            
            Group {
                Text(" ")
                    .font(paddingFont)
                +
                Text("Assasin's Creed")
                    .font(font)
                +
                Text(" ")
                    .font(paddingFont)
            }   .offset(x: -20)
        }
    }

Note that this problem also occurs with the Zapfino font (which is an iOS system font).

Upvotes: 0

Related Questions