【问题标题】:How do I programmatically change a custom view object's member variables?如何以编程方式更改自定义视图对象的成员变量?
【发布时间】:2011-09-05 04:43:35
【问题描述】:

感谢您抽出宝贵时间阅读本文,希望能帮到我!

我正在 Xcode 4 中编写我的第一个程序,这是第一次使用 Objective-C 和 Cocoa。我一直在关注教程,但此时我想使用自定义视图显示自定义图形,其中图形根据模型对象中的值而变化。

我的控制器类 GameController 基于 NSObject,在初始化期间创建我的模型对象,并成功接收按钮操作消息,适当地更新模型对象,并使用其出口更新窗口上的文本字符串作为回报。我通过在我的 xib 文件中创建一个 NSObject 对象(称为 MainMenu.xib 的默认 (?) 名称,但它包括我的应用程序中的所有 UI),使用实用程序窗格将其类设置为 GameController 来完成此操作,并且然后将其操作和出口连接到适当的 UI 元素。

我已将自定义视图拖到我的窗口中,并使用实用程序窗格将其类设置为我的自定义视图类 BoardView,它基于 NSView。在 BoardView 中,我重写了 drawRect: 以用蓝色填充视图的背景,然后绘制由我的模型类 (GameStatus) 定义的每个图形。

问题是,我不知道如何从我的 BoardView 类访问 GameStatus 中的数据,或者让 GameController 更新 BoardView 的成员变量。除了在 Interface Builder 中,我还没有通过在我的窗口上放置自定义视图来实例化 BoardView。我的 xib 文件(Interface Builder 左侧的列或列表)中没有 BoardView 对象。

我尝试在我的 GameController 类中创建一个 BoardView 对象的出口(正如我上面提到的,它在我的 xib 中有一个对象),并将该出口连接到我窗口中的 BoardView 自定义视图,界面生成器似乎没关系。但是,当我运行程序时,我的 GameController 类中 BoardView 插座指针的值是 0x0。似乎插座没有连接到 BoardView 对象。我不知道是否需要在 Interface Builder 中做其他事情来制作一个实际的对象(我尝试在左侧的列表中创建一个,但后来找不到将其连接到显示的实际自定义视图的方法窗户上)。

更令人困惑的是,当我运行我的应用程序时,窗口的 BoardView 区域将显示蓝色背景,实际上是我在 drawRect: 函数中定义的任何其他图形。但是,由于无法与我的模型对象对话,我无法根据模型的状态更改图形。我不确定硬编码图形正确显示的事实是否意味着某处有一个对象,或者它是否以某种方式基于类的通用模板进行绘制。后者对我来说真的没有意义,但如果前者是真的,我无法弄清楚如何从我的代码的其他部分与该对象交谈。

我觉得我只是缺少对 Xcode / Interface Builder 如何创建对象或其他东西的一些基本了解。我真的很感谢有人告诉我我在 MVC 对象/类之间的连接中缺少什么。

提前感谢您能给我的任何帮助!

编辑 2011/09/06: 要下载我的项目的副本以查看它,请转到此处: http://talix.homeip.net/2011/rival/ 那是我的家庭服务器,我是这方面的业余爱好者,所以如果它不起作用,请发表评论。谢谢!另外,如果除了编辑我的原始帖子之外,还有更好的方式来回复 cmets,请告诉我;我也是这个网站的新手。 ;-)

-乔

【问题讨论】:

  • 嗨,Joe,自定义视图显示蓝色背景色,因为您已将其类设置为 BoardView。我认为您遇到问题是因为您没有绑定正确的视图。您能否上传您的代码(或部分代码)并将链接提供给我们,以便我们检查到底是什么问题?
  • 我同意。上传您的代码,我们将立即解决问题!
  • @Miraaj,查看已编辑的问题以获取我的代码的链接,希望对您有所帮助!
  • @John,查看已编辑的问题以获取我的代码的链接,希望对您有所帮助!
  • @noa - 我的所有源代码,包括 GameController.m,都在我的源代码文件夹 Rival 中。该文件夹与我的 xcodeproj 文件位于同一文件夹中。两者都应该在我上面帖子中链接的文件夹中可用。

标签: xcode cocoa interface-builder custom-view


【解决方案1】:

听起来您只是在实例化一个GameController 和一个BoardView,而这发生在笔尖中。

那么,这就是问题的核心:

我尝试在我的 GameController 类中创建一个 BoardView 对象的出口(正如我上面提到的,它在我的 xib 中确实有一个对象),并将该出口连接到我窗口中的 BoardView 自定义视图,界面生成器似乎没关系。但是,当我运行程序时,我的 GameController 类中 BoardView 插座指针的值是 0x0。似乎插座没有连接到 BoardView 对象。

在您的代码中,您需要对 BoardView 的引用但得到了 nil?是在 GameController 的 init 方法中,还是在 GameController 的其他方法中?

如果它在 init 中,这就是我所期望的。加载 nib 的代码必须在连接插座之前初始化对象。

(如果它在 init 之外,我建议先断开并重新连接插座。)


  • 视图 = 板视图
  • 控制器 = 游戏控制器
  • 模型 = 游戏状态

在MVC中,控制器通常负责模型和视图之间的通信,所以我建议你这样处理:

  1. 将 gameController 插座添加到 BoardView 并将其连接到您的游戏控制器。
  2. drawRect 中,让 BoardView 从游戏控制器获取游戏状态。

我还建议您将 GameController 设为应用程序的代理:

  1. 删除RivalAppDelegate.[hm]
  2. 在您的 nib 中,删除对 Rival App Delegate 的引用,并将 Game Controller 引用连接到 File's Owner 代理插座。
  3. 您的笔尖中有两个 BoardView 实例。将窗口内的一个连接到 GameController 的 boardView 插座并删除另一个。
  4. GameController.h 中,在@interface GameController : NSObject 之后,添加<NSApplicationDelegate>
  5. GameController.m 中,实现applicationDidFinishLoading 并在那里设置您的应用程序。 (如果你愿意,你甚至可以在那里拨打setGameStatus。)

【讨论】:

  • 是的,BoardView 指针在GameControllerinit 方法中为零。这是否有助于以某种方式显示正在发生的事情?我尝试断开并重新连接插座,但似乎没有任何改变。
  • 我想我想问的是:在您的代码中,您需要对 BoardView 的引用但得到零?是在 GameController 的 init 方法中,还是在 GameController 的其他方法中? (插座将在 init 被调用之后连接,而不是之前。)
  • 如果在调用init 之后连接了插座,那肯定可以解释我遇到的问题。如果这是真的,您建议我在哪里/何时在我的班级之间建立联系?在RivalAppDelegate -applicationDidFinishLaunching?为了能够在那里引用我的GameController 对象实例,我是否需要在AppDelegate 对象和GameController 对象之间建立另一个插座和IB 连接?
猜你喜欢
  • 2019-04-11
  • 2017-06-18
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多