Reputation: 8830
In the attached code example I get a lot of extra top-spacing in my TextField. If I change the content to only be a single line, say "content", then it fits snugly. How can I get the same tight-fitting behaviour the single line has for a multi-line text?
Previews and code were made with Xcode 11.1 / Swift 5.1
import SwiftUI
struct TextFieldDemo: View {
var content: Binding<String>
init(content: Binding<String>) {
self.content = content
}
var body: some View {
TextField("Custom placeholder", text: content)
.background(Color.yellow)
}
}
#if DEBUG
struct TextInputRowPreviews: PreviewProvider {
static var previews: some View {
let content = "content\ncontent\ncontent\ncontent\ncontent\ncontent"
return TextFieldDemo(content: .constant(content))
.previewLayout(.sizeThatFits)
}
}
#endif
Here is the example if I change the "let content" line to
let content = "content"
Upvotes: 2
Views: 5249
Reputation: 11539
It seems there's no direct argument to manage multiline padding correctly. They are maybe underdevelopping. But the following will give you a straight workaround solution to what you are expecting.
extension String{
var extraLines : String{ get{
return self + String(repeating:"\n", count: self.components(separatedBy: "\n").count - 1)
}}
}
struct TextFieldDemo: View {
var content: Binding<String>
init(content: Binding<String>) {
self.content = content
}
@State var height : CGFloat? //current height
let constHeightRatio : CGFloat = 0.55 //use for assembly with other fonts.
let defaultHeight : CGFloat = 250 //use for assembly with other views.
var body: some View {
TextField("Custom placeholder", text: content).environment(\.multilineTextAlignment, .center).alignmentGuide(.bottom) { (ViewDimensions) -> CGFloat in
if self.height == nil {self.height = ViewDimensions.height}
return ViewDimensions.height
}.frame( height: (height ?? defaultHeight) * constHeightRatio, alignment: .bottom).background(Color.yellow)
}
}
#if DEBUG
struct TextInputRowPreviews: PreviewProvider {
static var previews: some View {
let content = "content\ncontent\ncontent".extraLines
return
TextFieldDemo(content: .constant(content))
}
}
#endif
This works fine for single view. If view assembly is required (with other stacking views, etc), you may adjust defaultHeight
and/or constHeightRatio
to achieve what you want. Hopefully it works for you too.
Upvotes: 2