如何保持模特和控制器与基于CALayer的UI分开?

时间:2009-07-04 17:03:04

标签: objective-c cocoa cocoa-touch calayer

我正在尝试重新实现一个旧的Reversi board game我用更多时髦的UI编写。我已经看过Jens Alfke的GeekGameBoard代码以获得灵感,而CALayers看起来就像是实现UI的方式。

然而,GeekGameBoard代码中没有模型和视图的清晰分离;模型视图,这使得很难例如制作游戏状态的副本以便为AI玩家执行游戏树搜索。但是,我似乎无法想出一种结构的替代方法,它允许模型和视图的分离,不需要持续战斗来保持两个平行的网格(对于模型,一个用于视图)同步当然,这有其自身的问题。

如何最好地实现AI搜索友好模型结构与显示友好视图之间的关系?任何建议/经验将不胜感激。我害怕/有一半期待一个答案,就是“没有好的答案:尽可能地处理它”,但我已经准备好对此感到惊讶!


感谢Peter的回答。但是,我并不完全确定我完全理解它。我可以看到这是如何工作的,如果你只是有一组最初的动作,甚至被删除,但是当一个人放下新作品时会发生什么?它会这样工作:

  1. 用户点击视图。
  2. 查看点击转换为电路板位置,并通知控制器。
  3. Controller创建一个具有后继状态的新董事会(如果合适,即合法移动)。
  4. 视图通过其绑定拾取新板,拆除现有视图/图层层次结构并将其替换为当前状态。
  5. 这听起来不错吗?

    PS:很抱歉没有说明它是针对iPhone还是Mac。我最感兴趣的是适用于iPhone的东西,但是如果我能在Mac上很好地使用它,我确信我可以自己调整解决方案以适应iPhone。 (或发布一个新问题!)

2 个答案:

答案 0 :(得分:2)

理论上,它应该与基于NSView的UI相同:添加模型属性(或属性),将其(或它们)作为绑定公开,然后通过控制器将视图(图层)绑定到模型

例如,你可能有一个带有Pieces的Board类(每个Piece都有一个对拥有它的玩家的引用),所有这些都是模型类。您的控制器将拥有一个Board,您的视图/图层将能够显示一个Board,可能还有每个Piece的子视图/子图层。

您将您的棋盘视图/图层绑定到控制器的board属性,并在您的视图/图层的该属性的setter中,为每个棋子创建一个子视图/子图层,并将其绑定到任何属性它需要的部分。 (更换主视图/图层板时,不要忘记取消绑定并删除所有子视图/子图层。)

当你想要移动或修改一块时,你可以使用它自己的属性;这些将转换为视图/图层上的属性访问。从表面上看,您将设置图层的属性以设置更改动画(例如,更改图块的position将导致图层相应移动。)

董事会也是如此。您可以让用户更改其中一种或两种图块颜色;你将通过游戏控制器将你的颜色绑定到它的Board对象,并且视图/图层绑定到同一个Board的相同属性,它将自动获取更改。

免责声明:我从来没有使用过Core Animation,如果你问的是Cocoa Touch而不是Cocoa,上面的解决方案将不起作用,因为它依赖于Cocoa Bindings。

答案 1 :(得分:0)

我有an iPhone application,其中几乎所有界面都是使用Core Animation CALayers构建的,我使用了与Peter描述的非常相似的模式。他是正确的,因为你想把你的CALayers看作是NSViews / UIViews,并通过模型对象通过控制器和数据管理他们的逻辑。

在我的例子中,我创建了一个控制器对象的层次结构,它也可以作为模型对象(我可以重构以拆分模型组件)。每个控制器对象都管理一个CALayer,因此最终成为模型控制器的并行CALayer显示层次结构。对于我的应用程序,我需要对使用此层次结构构造的方程执行计算,因此我使用控制器从树的底部提供计算值。控制器还处理用户编辑事件,例如插入新的子操作或删除操作树。

我已经创建了一个图层托管视图类,它允许CALayer树响应触摸或鼠标事件(其源代码现在在Core Plot项目中可用)。对于您的桌面游戏示例,CALayer部件可以接收触摸事件,并让其控制器管理后端逻辑(确定合法移动等)。您应该能够移动部件并保持相同的控制器,而不会在每次移动时撕下一切。