How to Scale Text to Fit Parent View with Swiftui

How to scale text to fit parent view with SwiftUI?

One can use GeometryReader in order to make it also work in landscape mode.

It first checks if the width or the height is smaller and then adjusts the font size according to the smaller of these.

GeometryReader{g in
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.4: g.size.height * 0.4))
}
}

Sample Image
Sample Image

How can I make text resize automatically to fit within a frame in swiftUI?

you have two options

1 - first one is to make a scale factor to the text depending on it's frame so when you have a text of size 30 width and 30 height and the text is 50 word that will not fit into the text frame so you could use and the text will get smaller to fit into the frame of text

Text("text of 50 word").frame(width: 30, height: 30, alignment: .center).minimumScaleFactor(0.5)     

2 - second one is to use fixed-size modifier which will make the text fit into the text frame and make the text scrollable whether in vertical position or horizontal position using

fixedSize(horizontal: Bool, vertical: Bool)

check Apple docs for that
https://developer.apple.com/documentation/swiftui/menu/fixedsize(horizontal:vertical:)

SwiftUI scale text to fit the width and height

on UIKit minimumScaleFactor and minimumFontSize are ineffective unless you set adjustsFontSizeToFitWidth.

Instead of creating a VStack, you may want to place all the figures, separated by newlines, in a single text, and fit the text to the bounding rectangle.

With SwiftUI the solution looks like:

struct aView: View {
let array = [4, 5, 6]

var body: some View {
HStack(spacing: 100) {
Text(array.map {String($0)}.joined(separator: "\n"))
.font(.system(size: 1000))
.minimumScaleFactor(0.01)
.frame(width: 60, height: 300)
.border(Color.primary)
Text(array.map {String($0)}.joined(separator: "\n"))
.font(.system(size: 1000))
.minimumScaleFactor(0.01)
.frame(width: 30, height: 150)
.border(Color.primary)
}
}
}

SwiftUI Make parent view stretch to fit child view

Instead of wrapping the entire ZStack with the GeometryReader, wrap only the Rectangle where you need the size:

struct ItemDetailsRowView: View {
var itemDetails: ItemDetials

var body: some View {
ZStack(alignment: .leading) {
GeometryReader { geometry in
Rectangle().frame(width: geometry.size.width * itemDetails.stat/itemDetails.maxOfStat,
height: geometry.size.height)
.opacity(0.3)
.foregroundColor(Color(itemDetails.color))
}

HStack {
VStack(alignment: .leading) {
Text(itemDetails.title)
.font(.system(size: 20))
Text(itemDetails.rowOne)
.font(.system(size: 12))
.foregroundColor(.gray)
Text(itemDetails.rowTwo)
.font(.system(size: 12))
.foregroundColor(.gray)
}

}
}
}
}

Sample Image

Automatic adjust font size in Text() of Swiftui?

Use minimumScaleFactor(_:) https://developer.apple.com/documentation/swiftui/text/minimumscalefactor(_:)

struct ContentView: View {
var body: some View {
VStack{
Text("Test string")
.minimumScaleFactor(0.1) //<--Here
.frame(width: 15, height: 15)
}
}
}

SwiftUI: how to make a view fit into a certain size

Try to use conditional in VStack.
I've created a custom card view that you can use in your content view, with LazyVGrid + ForEach or simply with HStack and VStack.

struct CardView: View{
var playerName: String
var playerTeam: String
var playerPortrait: UIImage
var body: some
View{

//Control amount of spacing depend on amount of character in player's name
VStack(spacing: playerName.count > 13 ? -12 : 0) { //first
Image(uiImage: playerPortrait)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height:160)
.padding(10)

Text(playerName)
.foregroundColor(.black)
.multilineTextAlignment(.center)
.lineLimit(2)
.padding(5)

Text(playerTeam)
.foregroundColor(.black)
.multilineTextAlignment(.center)
.padding(5)
}.background(RoundedRectangle(cornerRadius: 15).stroke()).padding(5)
}
}

Adjust Image Size of Image to Parent View Size

If I understood correctly the intention was to fill proportionally, so

  ZStack{
Image(backgoundImage!)
.resizable() // for resizing
.scaledToFill() // << here !! // for filling image on ImageView

but in that case it can spread out of bounds, so it needs to be clipped in place of .frame applied, so either

ImageCard("image")
.frame(decide the size of the image)
.clipped() // << here !!

or, better, as already described inject dimension inside card and apply it there, like

    Image(backgoundImage!)
.resizable() // for resizing
.scaledToFill() // << here !!
.frame(decide the size of the image)
.clipped() // << here !!
.cornerRadius(5)
.shadow(color: .gray, radius: 6, x: 0, y: 3)
}


Related Topics



Leave a reply



Submit