O código a seguir funcionou muito bem como esperado até que eu joguei uma Text
visualização adicional escrita abaixo do Toggle
(está comentado no código abaixo). Quando faço isso, recebo um erro Geometry action is cycle between duplicate values. e o programa eventualmente trava (no X86 15.2). Ele não trava de verdade, mas parece preso em algum loop infinito de atualização consumindo 100% de um núcleo e comendo RAM. Mesmo erro no M3 15.1, exceto que ainda não consegui fazê-lo travar/travar.
Parece um novo erro, já que o Google não retorna resultados para ele.
Alguém viu algo parecido? Se sim, o que significa?
Há algum problema com o código ou isso é um sinal de um possível bug no SwiftUI?
struct CaptureSizeView: ViewModifier {
@Binding var size: CGSize
func body(content: Self.Content) -> some View {
content
.onGeometryChange(for: CGSize.self) { proxy in proxy.size }
action: { newValue in size = newValue }
}
}
public extension View {
func captureSize(_ size: Binding<CGSize>) -> some View {
modifier(CaptureSizeView(size: size))
}
}
public extension CGSize {
var aspectRatio: CGFloat { self.width / self.height }
}
struct ContentView: View {
@State private var clearSize: CGSize = .zero
@State private var isSquare: Bool = false
var body: some View {
HStack(alignment: .top) {
VStack(alignment: .leading) {
Toggle("Keep Square", isOn: $isSquare).toggleStyle(.switch)
// Uncomment: error "Geometry action is cycling between duplicate values."
// Text("available size: \(clearSize)")
}
.padding()
Divider()
VStack {
Text("Canvas")
.font(.largeTitle)
.fontWeight(.black)
Text("available size: \(clearSize)")
ZStack {
Color.clear
.border(.green)
.captureSize($clearSize)
.overlay {
Canvas { _, _ in
}
.aspectRatio(isSquare ? 1 : clearSize.aspectRatio, contentMode: .fit)
.background(.yellow)
}
}
.padding()
}
}
}
}
Consegui reproduzir o problema executando seu código no macOS 15.1.1 (um MacBook Pro com Apple M1 Pro).
Sua visão é dividida em um lado esquerdo e um lado direito:
Text
saída que exibe o tamanho. Isso ocorre porque a largura do texto é maior do que a largura necessária para o controle de alternância que é mostrado acima dele no lado esquerdo.ZStack
com umColor
(e umCanvas
como sobreposição).Quando o tamanho da janela é alterado, isso faz com que o tamanho da janela
ZStack
seja alterado. Quando o novo tamanho é exibido, o texto (provavelmente) tem uma largura diferente do tamanho que estava sendo exibido antes, porque uma fonte proporcional está sendo usada para exibir o tamanho. Então, a mudança noText
tamanho causa outra mudança noZStack
tamanho. A última mudança noZStack
tamanho causa outra mudança naText
largura. E assim por diante.Para corrigir, você precisa evitar que uma alteração no tamanho
ZStack
cause um efeito cascata que resulte em outra alteração noZStack
tamanho.