- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望通过物理摇动设备来触发SwiftUI功能。由于此时运动检测还不是SwiftUI的功能,因此我需要将UIKit集成与协调器一起使用以返回Bool值,该值指示设备已被摇晃,从而触发了SwiftUI函数。
以下代码在识别设备的晃动方面都非常有效(这已由单独的“makeShakerSound()”函数证明,该函数在晃动时会播放声音片段,并且效果很好)。除了可以识别震动的工作代码外,我还包括下面用于从ContentView调用ShakableViewRepresentable(isShaken:$ shakeOccurred)的代码。
我创建了一个EnvironmentObject来标记设备已摇晃,并使用objectWillChange宣布已发生更改。
我的问题是:检测到震动时,震动效果很好,但是我的ContentView并未针对环境对象myDevice.isShaken中的更改进行更新。我以为使用objectWillChange可能会解决这个问题,但事实并非如此。我想念什么?
抱歉-我有点新。
/* CREATE AN ENVIRONMENTAL OBJECT TO INDICATE DEVICE HAS BEEN SHAKEN */
import Combine
import SwiftUI
class MyDevice: ObservableObject {
// let objectWillChange = ObservableObjectPublisher()
var isShaken: Bool = false {
willSet {
self.objectWillChange.send()
}
}
}
/* DETECT SHAKE GESTURE AND FLAG THAT SHAKING HAS OCCURRED */
import UIKit
import SwiftUI
struct ShakableViewRepresentable: UIViewControllerRepresentable {
class Coordinator: NSObject {
var parent: ShakableViewRepresentable
init(_ parent: ShakableViewRepresentable) {
self.parent = parent
}
}
func makeCoordinator() -> ShakableViewRepresentable.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> ShakableViewController {
ShakableViewController()
}
func updateUIViewController(_ uiViewController: ShakableViewController, context: Context) {}
}
class ShakableViewController: UIViewController {
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
guard motion == .motionShake else { return }
/* SHAKING GESTURE WAS DETECTED */
myDevice?.isShaken = true /* ContentView doesn't update! */
makeShakerSound() /* This works great */
/* I’M TRYING TO TRIGGER A FUNCTION IN SWIFTUI BY SHAKING THE DEVICE: Despite setting the myDevice.isShaken environment object to "true", my ContentView doesn't update when the shaking gesture is detected. */
}
}
ContentView.swift
@EnvironmentObject var myDevice: MyDevice
var body: some View {
NavigationView {
ZStack {
/* DETECT SHAKE GESTURE - This works */
ShakableViewRepresentable()
.allowsHitTesting(false)
VStack {
/* SHOW CURRENT STATE OF myDevice.isShaken - Doesn't update */
Text(self.myDevice.isShaken ? "The device has been shaken" : "No shaking has occurred")
Text("Device was shaken: \(self.myDevice.isShaken.description)")
}
/* more views below */
最佳答案
例
import SwiftUI
import Combine
class MyDevice: ObservableObject {
//let objectWillChange = ObservableObjectPublisher()
var isShaken: Bool = false {
willSet {
self.objectWillChange.send()
}
}
}
struct ContentView: View {
@ObservedObject var model = MyDevice()
var body: some View {
VStack {
Text("\(model.isShaken.description)").onTapGesture {
self.model.isShaken.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
let objectWillChange = ObservableObjectPublisher()
import SwiftUI
import Combine
class MyDevice: ObservableObject {
//let objectWillChange = ObservableObjectPublisher()
var isShaken: Bool = false {
willSet {
self.objectWillChange.send()
}
}
}
struct ContentView: View {
@EnvironmentObject var model: MyDevice
var body: some View {
VStack {
Text("\(model.isShaken.description)").onTapGesture {
self.model.isShaken.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(MyDevice())
}
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView().environmentObject(MyDevice())
//let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
myDevice?.isShaken = true
import UIKit
import SwiftUI
let model = MyDevice()
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView().environmentObject(model)
//let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
import SwiftUI
import Combine
struct ShakableViewRepresentable: UIViewControllerRepresentable {
class Coordinator: NSObject {
var parent: ShakableViewRepresentable
init(_ parent: ShakableViewRepresentable) {
self.parent = parent
}
}
func makeCoordinator() -> ShakableViewRepresentable.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> ShakableViewController {
ShakableViewController()
}
func updateUIViewController(_ uiViewController: ShakableViewController, context: Context) {}
}
class ShakableViewController: UIViewController {
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
guard motion == .motionShake else { return }
model.isShaken.toggle()
print(model.isShaken)
}
}
class MyDevice: ObservableObject {
//let objectWillChange = ObservableObjectPublisher()
var isShaken: Bool = false {
willSet {
self.objectWillChange.send()
}
}
}
struct ContentView: View {
@EnvironmentObject var model: MyDevice
var body: some View {
VStack {
ShakableViewRepresentable()
.allowsHitTesting(false)
Text(self.model.isShaken ? "The device has been shaken" : "No shaking has occurred").onTapGesture {
self.model.isShaken.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(MyDevice())
}
}
true
false
true
false
true
关于ios - 在SwiftUI中从摇动手势(使用UIKit)设置EnvironmentObject不会更新View,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60157510/
我正试图从这里众所周知的新手深渊中爬出来。 我开始掌握 @EnvironmentObject 的使用,直到我注意到文档中的 .environmentObject() View 运算符。 这是我的代码:
在我的 ContentView ,我有一个简单的按钮 sheet我的礼物SettingsView .好像和我的@EnvironmentObject var iconSettings: IconName
#SwiftUI 中似乎存在一个错误,其中 @EnvironmentObject如果用户拉下模态表以关闭它,但取消手势使其保持打开状态,则将不再可用。 实际错误: SwiftUI:0: Fatal e
我有一个使用 Storyboard 和 UIKit 构建的 iOS 项目。现在我想使用 SwiftUI 开发新屏幕。我向现有的 Storyboard 添加了一个托管 View Controller ,
SwiftUI 中的@Environment 和@EnvironmentObject 有什么区别? 从我从文档中找到的内容来看,@Environment 似乎是用于像 ColorScheme 这样的全
我想要一个变量作为 EnvironmentObject 并且我也希望它被持久化,这样每次我重新启动我的应用程序时它都是一样的。 为此,我已经创建了以下 propertyWrapper: import
我想从 Delegate 类中为 EnvironmentObject 设置值。 struct AppleMapView: UIViewRepresentable { @EnvironmentObj
我最近发现需要编写一个 Class 的 Mock,因为它会导致 SwiftUI preview 无法正常工作。不幸的是,我得到了错误: Property type 'T' does not match
我的应用程序中有三个 View 。第一个显示游戏列表。第二个是每场比赛的球员名单。第三个有每个玩家的得分列表。所以结构看起来像这样: struct GameView: View { @enviro
我有一个在工作线程中更新的@EnvironmentObject,并且几个 SwiftUI View 订阅了对已发布值的更改。 这一切都很好。 但我正在努力让 UIView 订阅@Environment
我有这种奇怪的行为,我已经尝试修复了好几个小时: 当 EnvironmentObject UserSettings 更改时,我的一个 View 未更新。尽管如果我完全重新启动应用程序,新值将按原样使用
我一直在阅读有关 SwiftUI 中的属性包装器的信息,我发现它们做得很好,但我真正不明白的一件事是 之间的区别。 @EnvironmentObject 和 @ObservedObject . 从我到
我试图在我的 URLSession 中更新 environmentObject。 我的登录 View 。 struct LoginView: View { @EnvironmentObject
是否可以在新的 SwiftUI 2.0 项目的应用程序文件中使用 EnvironmentObject? 我正在使用以下代码,但出现错误: Fatal error: No ObservableObjec
我成功地将 environmentObject appSettings 传递到我的 View 中。我可以使用它来修改我的字体和 View 中的选择器。但是,如果我尝试在 View init() 中访问
我遇到以下 SwiftUI 错误 @EnvironmentObject与自定义 Shape 一起使用时, : Fatal error: No ObservableObject of type MyOb
我用我的 @EnvironmentObject让我的 TeamData 可以被不同的人使用,但效果不佳。当我通过列表中的导航链接转到另一个 View 时,这很好。当我点击同一 View 的按钮时,它崩
我有一个 LoginView,如果用户未登录,则显示 RegisterView,如果用户已登录,则显示 ContentView: struct LoginView: View { @Envir
我正在尝试使用 @EnvironmentObject 来控制我的应用程序的某些方面。我遇到的问题是我的一个 Controller 无法访问环境对象。我收到 fatal error “未找到环境类型的
我在将类信息从一个结构实例传递到另一个结构实例时遇到了麻烦,所以我一直在尝试解决问题。 这是可行的,因为我正在通过 View // phone_testingApp.swift import Swif
我是一名优秀的程序员,十分优秀!