swift - SwiftUI - 将视图从手势移动到圆周不起作用
问题描述
我正在自动移动圆周上的视图。除此之外,我想用手势移动圆周。自动播放会定期移动,手势会根据手势的速度移动。
- 漏洞
存在视图在某个点旋转 360° 的错误。我认为action.gesture的计算方式不同,但我不知道正确答案。
你知道我的计算出了什么问题吗?
import Combine
import SwiftUI
import ComposableArchitecture
fileprivate let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
fileprivate let circleWidth: CGFloat = 300
// MARK: - State
struct CircleState: Equatable {
@BindableState var angle: Double = .zero
@BindableState var handling: Bool = false
@BindableState var handleLastAngle: CGFloat = 0
@BindableState var isTurnRight: Bool = true
var checkTurnRightValue: Double = .zero
}
// MARK: - Action
enum CircleAction: Equatable {
case gesture(DragGesture.Value)
case endGesture
case auto
}
// MARK: - Reducer
let circleReducer = Reducer<
CircleState, CircleAction, SignInEnvironment
> { state, action, environment in
switch action {
case let .gesture(v):
var theta = (atan2(v.location.x - circleWidth / 2, circleWidth / 2 - v.location.y)
- atan2(v.startLocation.x - circleWidth / 2, circleWidth / 2 - v.startLocation.y)) * 180 / .pi
if (theta < 0) { theta += 360 }
state.isTurnRight = state.checkTurnRightValue < theta
state.checkTurnRightValue = theta
state.angle = theta + state.handleLastAngle
case .auto:
if state.handling { break }
if state.isTurnRight {
state.angle += 0.1
} else {
state.angle -= 0.1
}
case .endGesture:
state.handling = false
state.handleLastAngle = state.angle
break
}
return .none
}
struct CircleView: View {
let store: Store<CircleState, CircleAction>
init(store: Store<CircleState, CircleAction>) {
self.store = store
}
var body: some View {
WithViewStore(self.store) { viewStore in
ZStack {
Circle()
.strokeBorder(Color.black, lineWidth: 2)
.frame(width: circleWidth, height: circleWidth)
Circle()
.foregroundColor(.red)
.frame(width: 60, height: 60)
.overlay(
Text("Hi")
.rotationEffect(.degrees(-viewStore.angle))
)
.offset(x: circleWidth / 2)
.onReceive(timer) { _ in
viewStore.send(.auto)
}
.animation(.default)
.rotationEffect(.degrees(viewStore.angle))
}
.gesture(
DragGesture()
.onChanged { v in viewStore.send(.gesture(v))}
.onEnded { _ in viewStore.send(.endGesture) }
)
.navigationBarHidden(true)
}
}
}
struct CircleView_Previews: PreviewProvider {
static var previews: some View {
CircleView(store:Store(
initialState: CircleState(),
reducer: circleReducer,
environment: SignInEnvironment(mainQueue: .main, signinClient: SignInClient.signin)
))
}
}
谢谢你。
解决方案
推荐阅读
- c++ - 如何处理指针
- javascript - ReactJS:使用 api 变量的图像导入问题
- azure - 无法从 Azure 逻辑应用连接到 Azure DevOps
- python - 从相似(但略有不同)的信息中得出不同的观点?
- python - ModuleNotFoundError:没有名为“book”django的模块
- python - 无法在 seaborn 热图动画中正确标记刻度线
- c++ - 如何使用 Eclipse(4.20.0 版本)和 Matlab(R2021a)在 Windows 中编译 mex 函数
- php - MySQL 错误:无法添加外键约束(PrestaShop 模块)
- c# - Auto/ManualResetEvent 是否同步内存访问?
- javascript - 如何在反应中为嵌套的对象数组设置状态?