簡體   English   中英

基於位於 SwiftUI 中該視圖內部的 GeometryReader 設置視圖框架

[英]Setting View frame based on GeometryReader located inside that View in SwiftUI

作為我努力學習新技術的一部分,我正在嘗試在 SwiftUI 中實現我正在開發的應用程序的屏幕之一。 我有這個粗略的布局:

在此處輸入圖像描述

此元素應拉伸以適應容器大小(不同寬度的設備),並將在 ScrollView 中使用。

這是我經過一番摸索后得出的初步解決方案:

在此處輸入圖像描述

這對於第一次嘗試來說效果很好,但我想通過將所有相關部分移動到一個單獨的視圖中來重構視圖。 除此之外,我希望新視圖能夠自動考慮填充和我稍后可能添加的其他大小修改。

所以,這是一個天真的重寫:

在此處輸入圖像描述

您可以很容易地發現,ScrollView 中的 GeometryReader 假定父級為其提供的大小,從而有效地隱藏了大部分視圖。

對於這種情況有幾種“骯臟”的解決方案:為視圖設置一個固定的框架高度,設置一個接近正確大小的寬高比(有點棘手,因為有固定高度的文本視圖),將 GeometryReader 保持在最外層主視圖的元素並將寬度作為初始化參數傳遞給子視圖。

我正在為這個特定的布局尋找一個“干凈”的解決方案,也許是為了更全面地了解 SwiftUI 的 Views 如何調節它們的大小——在 WWDC 視頻中,據說父 View 提出了一個大小,但隨后 child View 返回了它自己的尺寸; 有沒有辦法以某種方式干擾該過程,還是全部通過私有 API 完成?

謝謝!

–巴格蘭

ps 我認為除了 UI 預覽之外的代碼截圖將是最具說明性的,但如果我也應該提供代碼片段,請告訴我!

我相信我的回答應該是評論,但由於它會很長,所以我將其作為答案發布。 我回答了一個類似的問題,是否可以帶來更多的啟發。

在哪個View組件中使用GeometryReader很重要。

  • 如果您在一個典型的View中,該 View 的寬度達到屏幕的大小,您將獲得屏幕本身的widthheight

  • 如果您在ScrollView環境中,您會得到

    • .horizontal 對.horizontal器的height
    • 垂直對.vertical器的width

通常,未指定對齊方式的ScrollView顯式默認為.vertical


我想,設計決定是正確的。 因為如果您從UIKit中回憶起UIScrollView ,則滾動視圖中有一個內容視圖 在添加一些內容之前,您不知道內容視圖的大小。 SwiftUI中, ScrollView中的GeometryReader模仿了UIScrollView內容視圖的數學運算。 這就是原因,您無法從幾何閱讀器獲得實際尺寸。

此代碼工作正常:

struct GeometryReaderExperiment: View {
    var body: some View {

        GeometryReader { geometry in

            ScrollView {

                Text("First")

                DesignedFancy(parentGeometry: geometry, rectangleColor: .red)

                Text("Second")

                DesignedFancy(parentGeometry: geometry, rectangleColor: .green)

                Text("Third")

                DesignedFancy(parentGeometry: geometry, rectangleColor: .blue)

            }

        }

    }
}

struct DesignedFancy: View {

    var parentGeometry: GeometryProxy
    var rectangleColor: Color

    var body: some View {

        HStack(alignment: .bottom) {
            VStack {
                Rectangle()
                    .aspectRatio(1, contentMode: .fit)
                    .foregroundColor(rectangleColor)

                Text("One")
            }
            .frame(width: parentGeometry.size.width * 2/3)

            VStack {
                Rectangle()
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(rectangleColor)
                Text("Two")
            }

        }

    }

}

我認為問題是DesignedFancy不知道它有多少空間。 因此,您必須通過變量提供此信息。 結果是:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM