固定另一个尺寸时,SwiftUI View如何在一个尺寸上调整其理想尺寸?

时间:2020-05-17 17:06:42

标签: ios swift swiftui

.leftbar.open如何在夹紧另一维时调整其理想尺寸?

例如,View表现出这种行为。如果通过Text进行了限制,并且在一个维度上的空间太小,则另一维度的理想尺寸会相应地增大(如果可能)。

使用 .fixedSize

使用 .fixedSize(horizontal: false, vertical: false)

使用 .fixedSize(horizontal: false, vertical: true)

在前两种情况下,.fixedSize(horizontal: true, vertical: false)似乎已经将其理想大小定义为Text。但是,令我感到困惑的部分是,它似乎在第三种情况下将其修改为.frame(idealWidth: 400, idealHeight: 20)之类的东西。

我们如何像.frame(idealWidth: 80, idealHeight: 100)一样,允许我们的Text更新其理想尺寸,以响应被夹紧的尺寸?

以下是我在上面描述的View中显示此行为的一些代码:

Text

使用这种字体并重复“ o”内容,VStack(spacing: 100) { Group { Text("ooooooooooooooooooooooooooooooooooo") .fixedSize(horizontal: false, vertical: false) Text("ooooooooooooooooooooooooooooooooooo") .fixedSize(horizontal: true, vertical: false) Text("ooooooooooooooooooooooooooooooooooo") .fixedSize(horizontal: false, vertical: true) } .background(Color.green) .frame(width: 75, height: 75) .background(Color.blue) } 希望基本具有等于7,000点的正方形空间(情况2的理想尺寸为338x20,情况3的68x108)。

如何在自定义Text中复制它? ViewminHeight不是静态的;它们取决于父级是否已确定尺寸。作为孩子,我们怎么能知道我们已经夹紧了哪些尺寸(如果有)?在每个示例中,父级建议的尺寸仍为75x75,那么子级视图可以访问其理想尺寸的基础是什么? minWidth如何做到这一点?

要使答案更具体,请考虑如何用自定义类的实例替换Text实例,该实例的行为与Text("oooooo")类似。即。尝试保持7,000点的面积,且最小高度为20点,宁愿先水平生长。

1 个答案:

答案 0 :(得分:2)

由于fixedSize的工作性质,这是有问题的:

  • 我们可以为minideal的{​​{1}}提供maxwidthheight值。
  • 我们必须预先提供它们,这是不可能的,因为水平/垂直定位的min <= ideal <= max值会有所不同。

GeometryReader包装器

enter image description here

注释的代码不言自明。

ideal

问题

  • import SwiftUI extension View { func frame(size: CGSize) -> some View { self.frame(width: size.width, height: size.height) } } struct TextLike: View { // It's like text, how much space we'd like to occupy var squareArea: CGFloat // Text() draws at least one line of text, we'll do the same private let preferredHeight: CGFloat = 20 // Preferred/Max width in case of one line of text private let preferredWidth: CGFloat init(squareArea: CGFloat) { self.squareArea = squareArea self.preferredWidth = squareArea / preferredHeight } var body: some View { GeometryReader { proxy in // Let's say that this is the text Color.green.opacity(0.5) .frame(size: self.size(withProxy: proxy)) } .frame( // Ideally we'd like to draw it as one line of text idealWidth: preferredWidth, // Maximum width equals to ideal width (one line of text) maxWidth: preferredWidth, // At least one line of text minHeight: preferredHeight, // Ideally we'd like to draw it as one line of text idealHeight: preferredHeight ) } private func size(withProxy proxy: GeometryProxy) -> CGSize { // // Good enough for the demonstration, but you should get PhD & read: // // https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html // https://stackoverflow.com/a/10335601/581190 // https://stackoverflow.com/a/10334868/581190 // // Also it must be generic enough to cover different devices, ... // // proxy.size.width on iPhone SE (2nd) = 350.0 // proxy.size.width on iPhone 11 Pro Max = 350.3333... // // Just be aware of this and provide proper logic. // let horizontalFix = abs(proxy.size.width.distance(to: preferredWidth)).isLessThanOrEqualTo(1.0) let verticalFix = abs(proxy.size.height.distance(to: preferredHeight)).isLessThanOrEqualTo(1.0) switch (horizontalFix, verticalFix) { case (true, _): // Horizontal fix -> use preferred (= max) width -> one line of text // Vertical is irrelevant, because we do prefer horizontal grow return CGSize(width: preferredWidth, height: preferredHeight) case (false, false): // Use the offered size -> fits container, possible truncation return proxy.size case (false, true): // Vertical fix -> use offered width & calculate height return CGSize(width: proxy.size.width, height: squareArea / proxy.size.width) } } } struct ContentView: View { var body: some View { VStack(spacing: 50) { Group { TextLike(squareArea: 7000) .fixedSize(horizontal: false, vertical: false) TextLike(squareArea: 7000) .fixedSize(horizontal: true, vertical: false) TextLike(squareArea: 7000) .fixedSize(horizontal: false, vertical: true) TextLike(squareArea: 7000) .fixedSize(horizontal: true, vertical: true) } .frame(width: 75, height: 75) .background(Color.blue) } } } 充当包装器,并且其中包含实际视图(另外一层)。
  • 例如,我们不能在其上使用TextLike修饰符。

让我们像以前一样在background级别上修改代码并使用background修饰符。

TextLike

这是发生了什么

enter image description here

坦白地说,这不是理想且不错的选择,但是我现在可以得到最接近的