在 Swift 中,如何在视图控制器中找到 UILayoutGuide 对象?

Posted

技术标签:

【中文标题】在 Swift 中,如何在视图控制器中找到 UILayoutGuide 对象?【英文标题】:In Swift, how do you find UILayoutGuide objects in a view controller? 【发布时间】:2016-10-02 06:49:35 【问题描述】:

我正在使用 81 个按钮(在堆栈视图中组织)创建一个数独风格的 swift 应用程序。我使用它们的标记值 0 到 80 来引用按钮,这与我用来存储数组的数组对齐 但是,第一个按钮会导致问题,我认为是因为 UILayoutGuide 对象也有标签 0。

此解决方案有效,但我刚刚升级到 Xcode 版本 8.0 (8A218a) 并转换为 swift 3。

我在视图控制器的viewDidLoad函数中添加了如下代码:

// Get the subviews of the view
var subviews = view.subviews

// Return if there are no subviews
if subviews.count == 0 
    return


for subview : AnyObject in subviews

    // Do what you want to do with the subview
    print("\(subview.tag) - \(subview)")


这会产生以下日志:

可选(200) - UIImageView: 0x7ff3e240f3b0;帧 = (-4 0; 383 667);自动调整大小 = RM+BM;用户交互启用 = 否;标签 = 200;层=

可选(200) - UIStackView: 0x7ff3e240f590;帧 = (7 103; 360 360);不透明=否;自动调整大小 = RM+BM;标签 = 200;层 = CATransformLayer: 0x6100002316a0

可选(200) - UIImageView: 0x7ff3e24111b0;帧 = (0 47; 375 436);自动调整大小 = RM+BM;用户交互启用 = 否;标签 = 200;层=CALayer:0x6100002344e0

可选(200) - UIToolbar: 0x7ff3e2637ff0;帧 = (0 623; 375 44);不透明=否;自动调整大小 = RM+BM;标签 = 200;层=CALayer:0x6000000343e0

可选(200) - UIImageView: 0x7ff3e26015f0;帧 = (63 228; 248 211);自动调整大小 = RM+BM;用户交互启用 = 否;标签 = 200;层=CALayer:0x600000034ea0

可选(200) - UILabel: 0x7ff3e263e2e0;帧 = (117 313; 141 41); text = '干得好';不透明=否;自动调整大小 = RM+BM;用户交互启用 = 否;标签 = 200;层 = _UILabelLayer: 0x600000093060

可选(200) - UIStackView: 0x7ff3e263e750;帧=(127 491;120 120);不透明=否;自动调整大小 = RM+BM;标签 = 200;层 = CATransformLayer: 0x600000035520

可选(0) - _UILayoutGuide: 0x7ff3e263ee80;帧 = (0 0; 0 0);隐藏=是;层=CALayer:0x600000035bc0

可选(0) - _UILayoutGuide: 0x7ff3e263f030;帧 = (0 0; 0 0);隐藏=是;层=CALayer:0x600000035c60

所以最后两行输出是我怀疑的 UILayoutGuide 对象。我没有对它们进行编码,它们不是层次结构中的对象。我如何看到它们/摆脱它们?

【问题讨论】:

【参考方案1】:

如果您只想阻止循环添加 _UILayoutGuide(属于 UILayoutSupport 类),请执行以下操作:

// Get the subviews of the view
var subviews = view.subviews

// Return if there are no subviews
if subviews.count == 0 
    return


for subview : AnyObject in subviews

    // Do what you want to do with the subview
    print("\(subview.tag) - \(subview)")

    // Check for whether is it a UILayout class or not
      if(subview is UILayoutSupport)
            //This section is executed when UILayoutGuide will come into play
            print("Don't add it to the stack")
       else 
            // Write your code in this section
       


您还可以打印堆栈,检查其中的 UILayoutGuide 并将其删除。

【讨论】:

我只是使用循环来显示 UILayoutGuide 对象存在于 ViewController 中。我不是故意创建它们的,也看不到它们在模型中的位置。我的代码引用了我想为 1 个按钮(在堆栈内)设置的标签 id 0,但是由于这些布局指南,有 3 个标签 id 为 0 的对象,当通过标签 id 引用按钮时会导致崩溃。所以我想删除 UILayoutGuide 对象或更改它们的标签,但我不知道如何找到它们。 @StruanK :- 默认情况下每个元素都有一个标签 0,所以你不能直接使用它。你可以做的是在你给标签的时候,使用(0 + Some Int value)。并且在您使用该元素时减去该 Int 值。【参考方案2】:

简单的答案是 UILayoutGuides 没有标签。当您打印 subview.tag 时,它的显示标签 = 0 时没有标签。所以按钮 0 的问题与 UILayoutGuide 无关。

我没有弄清楚标记 0 按钮的问题是什么,但我重新编码以避免使用标记 0。没有完全修复,但解决方案有效。

【讨论】:

以上是关于在 Swift 中,如何在视图控制器中找到 UILayoutGuide 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如果在 Parse 中找到,则输入邮政编码切换视图控制器(Swift 和 XCode)

如何在 Swift 中加载初始视图控制器?

在 Swift 中点击 Pagecontrol 时更改页面

如何在swift中最初打开一个表视图到选定的详细视图

如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?

如何在 Swift 的不同视图控制器中更新同一实体的属性?