我正在尝试在我的 ios 项目中使用 ReSwift,并且有一个关于如何处理我的 View 更改的问题。我发现我需要知道旧状态是什么,然后才能应用新状态提出的更改。在我的 react 项目中使用 redux 时,我从来不需要知道我的旧状态是什么。
我的特定用例是,我正在构建一个带有覆盖屏幕的 CameraView。从应用程序中的任何地方说一个 ViewController 我可以创建一个 CameraView 并触发它通过触发一个 Action 从其中打开一个 UIImagePickerController。这是一些代码:
//ViewController:
class MainViewController: UIViewController {
var cameraView: CameraView?
@IBOutlet weak var launchCameraButton: UIButton!
init() {
cameraView = CameraView(self)
}
@IBAction func launchCameraButtonClicked(_ sender: Any) {
store.dispatch(OpenCameraAction())
}
}
//CameraActions
struct OpenCameraAction: Action {}
struct CloseCameraAction: Action {}
//CameraState
struct CameraState {
var cameraIsVisible: Bool
}
func cameraReducer(state: CameraState?, action: Action) -> CameraState {
let initialState = state ?? CameraState()
switch action {
case _ as OpenCameraAction:
return CameraState(cameraIsVisible: true)
default:
return initialState
}
}
//CameraView
class CameraView: StoreSubscriber {
private var imagePicker: UIImagePickerController?
weak private var viewController: UIViewController?
init(viewController: UIViewController) {
self.viewController = viewController
super.init()
imagePicker = UIImagePickerController()
imagePicker?.allowsEditing = true
imagePicker?.sourceType = .camera
imagePicker?.cameraCaptureMode = .photo
imagePicker?.cameraDevice = .rear
imagePicker?.modalPresentationStyle = .fullScreen
imagePicker?.delegate = self
imagePicker?.showsCameraControls = false
store.subscribe(self) { subscription in
subscription.select { state in
state.camera
}
}
}
func newState(state: CameraState?) {
guard let state = state else {
return
}
if state.cameraIsVisible {
self.open()
} else if !state.cameraIsVisible {
self.close()
}
}
func open() {
if let imagePicker = self.imagePicker {
self.viewController?.present(
imagePicker,
animated: true
)
}
}
func close(){
self.imagePicker?.dismiss(animated: true)
}
}
以上就是打开和关闭相机的全部代码。当我们添加更多操作(例如禁用或启用闪光灯)时,我的困惑就开始了。在我看来,我需要处理额外的状态转换。
我的行动现在成长为:
struct OpenCameraAction: Action {}
struct CloseCameraAction: Action {}
struct FlashToggleAction: Action {}
我现在的状态是这样的:
struct CameraState {
var cameraIsVisible: Bool
var flashOn: Bool
}
// not showing reducer changes as it self explanatory
// what the state changes will be for my actions.
我的观点是并发症的开始。如果用户启用了 Flash 并且我正在响应 FlashToggleAction 状态更改,我该如何在我的 View 中处理状态更改?
func newState(state: CameraState?) {
guard let state = state else {
return
}
// this will get triggered regardless of whether
// a change in the flash happened or not.
self.toggleFlash(state.flashOn)
// now the below lines will be executed even though
// the only change was a flash on action.
//I don't want my camera to opened again or closed.
if state.cameraIsVisible {
self.open()
} else if !state.cameraIsVisible {
self.close()
}
}
我现在如何应对变化?我能想到的处理这个问题的唯一方法是存储对旧状态的引用并自己比较差异。
最佳答案
在这种情况下,我的第一个问题实际上是:您是否需要将其作为应用状态的一部分进行处理?是否需要有人通知相机状态变化?如果不是,请将其作为 UI 层中的实现细节。让 biew Controller 自行打开相机,拍摄生成的图像,然后发送 DoStuffWithImage(imageFromCam)。
这只是一般性建议:不要在 ReSwift 中为您的 UIKit 特定交互建模。对有趣的数据流进行建模。然后让 UI 组件朝着这个目标努力。
您真正的问题暗示:如何划分存储订阅者?
目前,您使用单个订阅者来解决与相机相关的问题。但是您也可以为每个可独立修改的组件编写 1 个订阅者。就像闪光灯切换一样。然后你只需要检查那里的闪光灯切换的状态变化,忽略其他设置;虽然在这种情况下,闪光灯切换可以利用知道他的相机是否真的打开了——或者你在相机关闭时重置闪光灯状态来解决这个问题,有效地移动“闪光灯” AND camera active”逻辑一直到 reducer 。
我可以想出更多的方法和想法,但最终归结为:您的应用程序中的组件是什么?相机状态控制是应用程序状态的核心部分,还是只是一个微小的细节?在设计过程的早期权衡这一点有助于找到合适的解决方案。
关于ios - ReSwift - 如何处理依赖于 View 中旧状态和新状态的状态更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45524400/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R