In a SwiftUI view, I have several Text
elements in a HStack
. Depending on the user input there will not be horizontal room to show all of the texts. The HStack
does it job fine by ensuring all of the Text
elements get equal widths and the strings are truncated. This is all as expected and as it should be.
The problem is that all the strings are truncated with a "..." in the end whereas I want the behaviour of UILabel.lineBreakMode = .byClipping
, that is the string should simply be cut off at the edge of the Text
element.
How do I achieve this?
Edit for more details on what I want:
import SwiftUI
struct TextClipPoC: View {
var body: some View {
HStack {
textElm
textElm
textElm
textElm
}
}
var textElm: some View {
Text("abcdefghijklmn")
.padding(.all, 3)
.background(Color.yellow)
}
}
struct TextClipPoC_Previews: PreviewProvider {
static var previews: some View {
TextClipPoC()
.previewLayout(.fixed(width: 320, height: 40))
}
}
gives this output:
I want the exact same output as above, except instead of "..." I want the text to just clip.
If I just add .fixedSize()
to the HStack
(or to the Text
elements), as suggested in a solution, I get this result:
One solution is to overlay two instances of the same Text
, one fixed size and one normal, let the normal one decide the size and hide it and then have the fixed size one clipped.
Can be done with a ViewModfier
:
struct FixedClipped: ViewModifier {
func body(content: Content) -> some View {
ZStack(alignment: .leading) {
content.hidden().layoutPriority(1)
content.fixedSize(horizontal: true, vertical: false)
}
.clipped()
}
}
extension View {
func fixedClipped() -> some View {
self.modifier(FixedClipped())
}
}
and then used like this:
struct TextClipPoC: View {
var body: some View {
HStack {
textElm
textElm
textElm
}
}
var textElm: some View {
Text("abcdefghijklmn")
.padding([.leading, .trailing], 3)
.background(Color.yellow)
.fixedClipped()
}
}
struct TextClipPoC_Previews: PreviewProvider {
static var previews: some View {
TextClipPoC()
.previewLayout(.fixed(width: 320, height: 40))
}
}
This produces this result:
To avoid truncation it needs to use fixed size, like
HStack {
... your text items here
}
.fixedSize()
everything else depends on context of usage and will require .clipped
at some upper container.
Other possible solution is to use deactivated ScrollView
, like
ScrollView(.horizontal) {
HStack {
... your text items here
}
}.disabled(true)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With