[英]SwiftUI View Sizing (Parent/Child Relationship)
我正在通過一些示例來熟悉 SwiftUI,但我遇到了尺寸問題。
我已經習慣了 UIKit 處理調整視圖大小的方式,使用 AutoLayout 您基本上可以為其子級設置父級大小。 SwiftUI 似乎不是這種情況。
我讀過的所有內容都顯示了如何在孩子上使用 GeometryReader 來獲取其父母的大小,然后孩子可以選擇自己的大小,但我還沒有看到如何從父母那里獲得孩子的大小.
假設我有以下代碼:
struct ContentView: View {
var body: some View {
Text("This is Text").ripple(rippleColor: .lightGray, rippleOpacity: 0.5)
}
}
ipple ripple()
是 function 的擴展,它添加了一個自定義ViewModifier
,該 ViewModifier 將內容覆蓋到UIViewRepresentable
視圖上,以便在點擊時創建材質波紋效果。
struct RippleModifier: ViewModifier {
let rippleColor: UIColor
let rippleOpacity: Float
func body(content: Content) -> some View {
RippleView(
rippleColor: rippleColor,
rippleOpacity: rippleOpacity
)
.overlay(content)
}
}
extension View {
func ripple(rippleColor: UIColor, rippleOpacity: Float) -> some View {
modifier(
RippleModifier(
rippleColor: rippleColor,
rippleOpacity: rippleOpacity
)
)
}
}
我遇到的問題是,當我只有Text
時,它會將其框架設置為適合其內容(字符串)。 當我向它添加.ripple()
修飾符時,框架就會變成整個屏幕。
使用 UIKit,我只需添加一些約束來將 UILabel 固定到父級,我會讓它決定父級的大小。
有沒有辦法處理 SwiftUI?
獎金問題:
相關但不相關,我如何讓Text
上的點擊進入它覆蓋的視圖? 當點擊視圖框架內的任何位置時,波紋將激活並正確動畫,但直接點擊文本本身除外。
這是 UIViewRepresentable 視圖的部分代碼。
struct RippleView: UIViewRepresentable {
var rippleColor: UIColor = .systemGray
var rippleOpacity: Float = 0.5
func makeUIView(context: Context) -> UIRippleView {
UIRippleView()
}
func updateUIView(
_ uiView: UIRippleView,
context: UIViewRepresentableContext<RippleView>
) {
uiView.rippleColor = rippleColor
uiView.rippleOpacity = rippleOpacity
}
}
open class UIRippleView: UIView {
open var rippleColor: UIColor = .systemGray {
didSet {
rippleLayer.fillColor = rippleColor.cgColor
}
}
open var rippleOpacity: Float = 0.5 {
didSet {
rippleLayer.opacity = rippleOpacity
}
}
private lazy var rippleLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.opacity = 0.0
self.layer.insertSublayer(layer, at: 0)
return layer
}()
public override init(frame: CGRect) {
super.init(frame: frame)
clipsToBounds = true
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
clipsToBounds = true
}
}
該視圖有一個擴展,它覆蓋了觸摸函數來計算點擊發生的位置並執行動畫,但這只是修改了rippleLayer
的path
。
您可以像這樣將overlay
更改為background
:
struct RippleModifier: ViewModifier {
let rippleColor: UIColor
let rippleOpacity: Float
func body(content: Content) -> some View {
content.background(
RippleView(
rippleColor: rippleColor,
rippleOpacity: rippleOpacity
))
}
}
所以RippleView
從content
中獲取大小約束,而不是相反。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.