我正在通过一些示例来熟悉SwiftUI,但是在调整大小方面存在问题。
我已经习惯了UIKit处理视图大小的方式,在这种情况下,您可以使用AutoLayout为其子级添加父级大小。 SwiftUI似乎并非如此。
我阅读的所有内容都表明了如何在孩子上使用GeometryReader来获取其父对象的尺寸,这表明孩子可以选择自己的尺寸,但是我还没有看到如何获取孩子的尺寸来自父母。
说我有以下代码:
struct ContentView: View {
var body: some View {
Text("This is Text").ripple(rippleColor: .lightGray, rippleOpacity: 0.5)
}
}
ripple()
是一个扩展功能,它添加了一个自定义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
}
}
该视图有一个扩展,它覆盖了触摸功能以计算点击发生的位置并执行动画,但是只是修改了path
的{{1}}。
答案 0 :(得分:1)
您可以像这样将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
获得大小约束,而不是相反。