I am attempting to achieve a layout within an HStack
that contains two views: A Text
view that may or may not contain multiple lines of text, and a Button
. These are aligned with the top edge of the containing HStack
.
For the purpose of this question, the Button
could be any kind of View
.
I want the height of the Button
to be equal to the height of the first line of the text contained within the Text
element.
This is easy when the Text
contains a single line - there are obvious ways to make two views equally tall. But it's unclear to me how to do this when the Text
contains multiple lines of text when the size of the text could differ based on accessibility settings, etc.
I know how to do this in UIKit, but am unsure of how to do it with SwiftUI. Does anybody have any ideas? Thanks!
I've included a screenshot showing more or less what I'm going for. In this example I've hardcoded the height of the Button
(so it looks pretty close), but this won't work if the Text
's font size changes for any reason.
Edit 1: What I've Tried
Not a whole lot. I think the solution hinges on being able to get the metrics of the font associated with the text displayed by the Text
, but it's not clear how to do so in SwiftUI. This font could come from anywhere, be derived from a Font.TextStyle
, and is subject to the user's Dynamic Type setting.
My searching for this has turned up nothing so far, hence my question here.
Edit 2: Code Sample
Below is code from my simplified hardcoded implementation. Here I (roughly) estimate the size of a .title3
TextStyle
to manually set the height of the Button
, but this is intended to be a generalized solution. So, when this is put in production the font could be any size (either derived from a TextStyle
or via some sort of system/custom font).
HStack(alignment: .top, spacing: 4.0, content: { Text(title) .font(.title3) .fontWeight(.medium) .frame(maxWidth: .infinity, alignment: .leading) .border(Color.gray) Button(action: { }, label: { Text("See More") .font(.caption) }) .frame(minHeight: 26.0, alignment: .center) .border(Color.gray)})