我有一个可以在屏幕上移动的灰色视图。灰色视图有一个随动画旋转的子视图(把它想象成一个时钟指针)。子视图旋转的Angular 直接与父视图用于其.offset()
或.position
的translation
值相关。
尽管我只是尝试为子视图的.rotationEffect()
设置动画,但它并没有停留在锚位置。
在下面的示例中,可以使用拖动手势或屏幕底部的按钮移动灰色视图,如果灰色视图向上移动,则子视图逆时针旋转,如果灰色视图向下移动,则子视图顺时针旋转。
如果子视图中没有.animation()
属性,它将正确旋转。
问题的Here is a Xcode Playground,代码如下:
import UIKit
import SwiftUI
import PlaygroundSupport
struct Example: View {
@State private var translation: CGSize = .zero
var body: some View {
ZStack {
movingView()
.overlay(rotatingView(), alignment: .top)
.overlay(anchorPoint())
.offset(translation)
.gesture(dragGesture())
controls()
}
}
}
private extension Example {
func rotatingView() -> some View {
Rectangle()
.fill(Color.red)
.frame(width: 4.0, height: 50.0)
.rotationEffect(angle, anchor: .bottom)
.animation(.interactiveSpring(), value: angle)
}
var angle: Angle {
let total = translation.height
return .degrees(total)
}
}
private extension Example {
func movingView() -> some View {
Color.gray
.frame(width: 100.0, height: 100.0)
}
func dragGesture() -> some Gesture {
DragGesture()
.onChanged { value in
self.translation = value.translation
}
.onEnded { value in
self.translation = .zero
}
}
}
private extension Example {
func anchorPoint() -> some View {
Circle()
.fill(Color.white)
.frame(width: 8.0, height: 8.0)
}
}
private extension Example {
func controls() -> some View {
VStack {
Spacer()
HStack {
Button("Up") {
withAnimation(.spring()) {
translation.height -= 100
}
}
Button("Down") {
withAnimation(.spring()) {
translation.height += 100
}
}
}
}
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = UIHostingController(
rootView: Example()
.frame(width: 500.0, height: 800.0)
)
1条答案
按热度按时间oxiaedzo1#
这可以通过在
.overlay(anchorPoint())
之后添加drawingGroup()
修饰符来解决,例如这会在最终显示之前将视图的内容合成到屏幕外图像中。
https://developer.apple.com/documentation/swiftui/navigationview/drawinggroup(opaque:colormode:)