Is it possible to hide backfaces when using SwiftUI rotation3DEffect?

我与影子孤独终老i 提交于 2021-01-28 05:18:54

问题


Consider this simple example:

import SwiftUI

struct RotationExample: View {

  var body: some View {
    ZStack {
      Color.red
      Text("Text I want to hide")
      .font(.system(size: 48))
    }
    .frame(width: size, height: size)
    .rotation3DEffect(Angle.degrees(180), axis: (x: 0, y:1, z: 0))
  }
}

struct RotationExample_Previews: PreviewProvider {
  static var previews: some View {
    RotationExample()
  }
}

When this code is run, the text is shown reversed. I thought when the rotation was applied, the layers would be respected (ie. the foreground layer would disappear behind the background)

Is it possible to hide a View when it is a backface rotated beyond 90 degrees, or to somehow get the layers to reverse during rotation? I have tried using .drawingGroup() and setting .background modifiers but neither worked.


回答1:


The rotation3DEffect is just a transformation to drawing context, ie. how to draw content, there is no any backface. If you want to draw different content then you have to provide it explicitly, like in below example.

struct RotationExample: View {
    @State private var flipped = false
    var body: some View {
        VStack {
            Button("Flip") { self.flipped.toggle() }
            ZStack {
                if flipped {   // 1st-side content
                    Color.red
                    Text("Text I want to hide")
                        .font(.system(size: 48))
                    .rotation3DEffect(Angle.degrees(180), axis: (x: 0, y:1, z: 0))
                } else {       // 2nd-side content
                    Color.blue
                }
            }
            .frame(width: 400, height: 100)
        }
    }
}



回答2:


Using computed properties it's possible to determine whether the layer should be shown or not - this allows for continous adjustments like the following where the rotation is on a drag gesture. The angle of rotation is based on the gesture, then the opacity is based on the angle:

import SwiftUI

struct RotationExample: View {

  @State var translation: CGSize = .zero

  var textOpacity: Double {
    let theta: Double = abs(angle.degrees).truncatingRemainder(dividingBy: 360)
    return theta >= 90 && theta <= 270 ? 0 : 1
  }

  var textOpacity: Double {
    return abs(angle.degrees) >= 90 ? 0 : 1
  }

  var body: some View {
    ZStack {
      Color.red

      Text("Text I want to hide")
      .font(.system(size: 48))
      .multilineTextAlignment(.center)
      .opacity(textOpacity)
    }
    .frame(width: size, height: size)
    .rotation3DEffect(angle, axis: (x: 0, y:1, z: 0))
    .gesture(DragGesture()
      .onChanged { value in
        self.translation = value.translation
      })
  }
}

struct RotationExample_Previews: PreviewProvider {
  static var previews: some View {
    RotationExample()
  }
}


来源:https://stackoverflow.com/questions/61621734/is-it-possible-to-hide-backfaces-when-using-swiftui-rotation3deffect

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!