1

I am trying to adapt the font size of a text element whose length varies greatly so that it fills the whole frame where it is located and no word needs to be truncated (in a iOS app). In the screenshot below, I would like the sentence to reach the buttons at the bottom of the screen.

Please find below the structure of my code. I have seen a few threads on SO dealing with this issue, but I have not been able to replicate the solution, because of my poor skills in Swift... If someone were so kind as to give me a detailed explanation of what lines of code should be inserted and where to place them, I'd be very grateful!

I have tried to adjust the font size so to say manually, by incrementing or decrementing it via a function according to the length of the string that Text receives as its argument, but it only yielded a mess, because long words need their own separate line, which mars my computation.

With thanks,

Julien


import SwiftUI
import AVKit
import UIKit
import AVFoundation
import Foundation
import CoreServices
import CoreData
import MediaPlayer

struct ContentView: View {

// Various functions
    
    @State var audioPlayer: AVAudioPlayer!
    
    var body: some View {
        
            VStack {
                
                var currentSentence = "string of variable length, could be a long or a very short sentence"
                Text(currentSentence) // the variable currentSentence contains a string whose length varies greatly
                    .font(.system(size: 40, weight: .light, design: .serif))
                
                HStack {

                    Spacer()
                    // Play button
                    Button(action: {
                    // Action
                    }) {
                        Image(systemName: "play.square.fill").resizable()
                            .frame(width: 150.0, height: 200.0, alignment: .bottom)
                    }
                    .frame(maxHeight: .infinity, alignment: .bottom)
                    Spacer()
                    // Pause button
                    Button(action: {
                    // Action
                    }){
                        Image(systemName: "square.slash").resizable()
                            .frame(width: 150.0, height: 200.0)
                            .aspectRatio(contentMode: .fill)
                    }
                    .frame(maxHeight: .infinity, alignment: .bottom)
                    Spacer()

               }
            }
            .frame(
                  minWidth: 0,
                  maxWidth: .infinity,
                  minHeight: 0,
                  maxHeight: .infinity,
                  alignment: .topLeading
                )
        }
    }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

app screenshot

2
  • 2
    You'll likely have more success here if you include a minimal reproducible example. The code you've included doesn't compile. Commented Jan 3, 2022 at 19:37
  • Thank you for your remark, I have rectified and slightly expanded the code outline, it now compiles and runs. I hope my goal is sufficiently clear, if there's anything else that I should state or add, please let me know. Commented Jan 4, 2022 at 11:19

1 Answer 1

1

You need to use .minimumScaleFactor on the text and set the text font to the maximum.

struct ContentView: View {
    var body: some View {
        VStack (spacing: 0) {
            
            var currentSentence = "string of variable length, could be a long or a very short sentence"
            Text(currentSentence)
                .font(.system(size: 100, weight: .light, design: .serif))
                .minimumScaleFactor(0.1) 
            Spacer()
            HStack (alignment: .bottom, spacing: 0) {
                
                Spacer()
                    // Play button
                Button(action: {
                        // Action
                }) {
                    Image(systemName: "play.square.fill").resizable()
                        .frame(width: 150.0, height: 200.0, alignment: .bottom)
                }
                Spacer()
                    // Pause button
                Button(action: {
                        // Action
                }){
                    Image(systemName: "square.slash").resizable()
                        .frame(width: 150.0, height: 200.0)
                        .aspectRatio(contentMode: .fill)
                }
                Spacer()
                
            }
        }
        .edgesIgnoringSafeArea([.bottom])
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}

In some cases there might be little bit space between text and buttons, It means new line with bigger font can't fit there.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much, it works wonderfully, I would never have come upon this solution by myself. I will have thankful thoughts for you whenever I use my app!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.