我正在创建一个Tic Tac Toe应用程序。当游戏重置时,所有X和Os UIButton
图像都应返回nil
。电路板中的每个空间都标记为0到8。
var buttonsToClear : UIButton
for var i = 0; i < 9; i++ {
buttonsToClear = view.viewWithTag(i) as! UIButton
buttonsToClear.setImage(nil, forState: .Normal)
}
在添加导航栏之前,一切正常。现在我收到错误消息
&#34;无法转换类型的值&#39; _UINavigationBarBackground&#39; (0x107e2f2a0)&gt;到&#39; UIButton&#39; (0x107e357e0)。 (LLDB)
我绝对相信我的新导航栏标签为&#34; 10&#34;。
还有什么可以触发此消息?
答案 0 :(得分:5)
您在逻辑上是正确的,您的代码将完美运行。
您收到错误
&#34;无法转换类型的值&#39; _UINavigationBarBackground&#39; (0x107e2f2a0)&gt;到&#39; UIButton&#39; (0x107e357e0)。 (LLDB)
因为,当for loop
运行时,第一个索引将为零,即i = 0,
buttonsToClear = view.viewWithTag(i) as! UIButton
将成为
buttonsToClear = view.viewWithTag(0) as! UIButton
因此,在这种情况下,您尝试使用tag
值0来获取视图。
UINavigationBarBackground
也有标记值0。
注意:
<强> 1。当系统找到两个具有相同标记值的视图,并且您尝试使用viewWithTag:
获取视图时,它将返回第一个视图。
<强> 2。每个视图都有默认标记值0。
第3。只需在故事板或XIB中拖动UILabel或UIView并检查其标记值。
因此,在您的情况下,它将返回UINavigationBarBackground
而不是UIButton
。因此,您无法将UINavigationBarBackground
输入UIButton
。
您的错误解决方案:
永远不要给从0开始的标签。 尝试给像1000这样的值开始标记。 所以你的第一个按钮将有标签1000,接下来将有1001,然后是1002等等。
写下你的for循环,如下所示。
var buttonsToClear : UIButton
for var i = 1000; i < 1009; i++ {
buttonsToClear = view.viewWithTag(i) as! UIButton
buttonsToClear.setImage(nil, forState: .Normal)
}
答案 1 :(得分:4)
你不应该使用0标签,因为0是默认的,你可以获得任何视图(在这种情况下是导航的背景)。
以1开始标记视图。
答案 2 :(得分:1)
您必须能够看到堆栈跟踪以查看其被触发的位置?在任何情况下,显而易见的解决方案是在调试器中运行它,打开异常断点并查看发生了什么。
正如何塞所说,不要使用标签0。
答案 3 :(得分:0)
问题是,您的循环遇到UINavigationBar
,_UINavigationBarBackground
上的私有媒体资源。由于您无法在此设置代码,因此它的默认代码为0
。因此,您将尝试向其发送UIButton
功能。
我只是遍历您的子视图并检查视图是否为UIButton
类型,然后然后检查它的标记(确保仍然不使用标记{{ 1}},因为这是默认标记),然后删除它。 这样您就可以100%确定您获得了正确的子视图。
0
答案 4 :(得分:-1)
导航栏中的按钮是UIBarButtonItem
而不是UIButton
,看起来标记的视图可能是UINavigationBar
,而不是UIBarButtonItem
。
我建议不要使用标签,如果您要使用标签,请使用常量而不是幻数。而不是标签将IBOutlet
添加到您想要更改的视图中。如果您希望清除大量按钮,则可以使用IBOutletCollection
,但是您再次在导航栏中遇到按钮问题UIBarButtonItem
并且不是UIButton
。
您可以将leftBarButtonItem
设置为UIBarButtonItem
,其自定义视图 为UIButton
,但是当您可以改变时,这似乎很迂回UIBarButtonItem
本身!