Quero desenhar uma imagem sobreposta a um painel desfocado com texto. O problema é que a moldura do painel depende da moldura do texto. Ao mesmo tempo, mask
o modificador de tempo é definido separadamente do texto e do painel.
Meu código:
struct SomeView: View {
@State var frame: CGRect = .zero
var body: some View {
ZStack {
Image(.defaultCard)
Image(.defaultCard)
.blur(radius: 30)
.mask {
Rectangle()
.frame(width: frame.width, height: frame.height)
.position(x: frame.midX, y: frame.midY)
}
ZStack(alignment: .bottomLeading) {
Color.clear
HStack {
Text("...")
Text("...")
}
.padding()
.background {
GeometryReader { geometry in
Color.clear
.onAppear {
frame = geometry.frame(in: .global)
}
.onChange(of: geometry.size) { _ in
frame = geometry.frame(in: .global)
}
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
Tudo está desenhado, mas a posição da máscara está incorreta. O código a seguir retorna um quadro incorreto:
frame = geometry.frame(in: .global)
Como resolver esse problema? Entendo que eu poderia usar o desfoque do UIKit, mas o desfoque do SwiftUI atende melhor às minhas necessidades.
Uma maneira de posicionar a máscara é usar
.matchedGeometryEffect
. Dessa forma, você não precisa medir o tamanho e a posição do painel.É necessário um valor A
Namespace
em vez de uma variável de estado e um identificador arbitrário para corresponder a máscara ao painel. O exemplo atualizado abaixo usa "Painel" como identificador.