简体   繁体   English

在Xcode 9 / Swift 4中不再可以访问本机UIKit元素的子视图吗?

[英]Native UIKit elements' subviews are no longer accessible in Xcode 9 / Swift 4?

The Story: 故事:

So I was looking over ways on how to hide a UIPickerView 's selection indicator, and I saw some SO threads that had a workaround. 因此,我正在研究如何隐藏UIPickerView的选择指示器的方法,并且看到一些具有解决方法的SO线程

However, when I tried using that in Xcode 9 (beta 4) with Swift 4, I found that it didn't work. 但是,当我尝试在Swift 4的Xcode 9(测试版4)中使用它时,我发现它不起作用。 Upon further inspection I realized that whenever I called myPickerView.subviews , I got a count of 0. Now this is weird as it apparently worked before as the other threads suggest. 经过进一步检查,我意识到,每当我调用myPickerView.subviews ,我的计数都为0。现在这很奇怪,因为它显然在其他线程建议的情况下就可以工作了。

I checked using the debug view hierarchy tool, and it seems that the subview structure is unchanged, with 3 subviews as older threads seem to have as well. 我使用调试视图层次结构工具进行了检查,看来子视图的结构没有变化,因为旧线程似乎也有3个子视图。 But for some reason I can't access them. 但是由于某些原因,我无法访问它们。 The incredible part though, is if I set the language to Swift 3.2 and run the same project on iOS 9.0 I still get the same error. 但是,令人难以置信的是,如果将语言设置为Swift 3.2并在iOS 9.0上运行相同的项目,我仍然会遇到相同的错误。 So I can't really tell when or where the change seems to originate. 因此,我无法真正确定更改的时间或来源。 I unfortunately don't have an older version of xcode to test on anymore. 不幸的是,我再也没有要测试的旧版本的xcode。

This same thing seems to happen with multiple UIKit elements though, but not all of them. 尽管多个UIKit元素似乎发生了相同的事情,但并非全部。 A full list is at the end of this post. 完整列表在这篇文章的结尾。 I've tried to be as comprehensive as possible, feel free to let me know if I missed anything. 我试图尽可能地全面,如果我错过了任何东西,请随时告诉我。

I know the correct way to solve this would be to make my own UIScrollView and customize it, but for future use and for the rest of the elements, anyone have any idea if there's a workaround to what already was a workaround? 我知道解决此问题的正确方法是制作自己的UIScrollView并对其进行自定义,但是对于将来的使用以及其他元素,任何人都不知道已有解决方法吗?

Elements that still have Subviews: 仍具有子视图的元素:

  • UISwitch : 1 Subview UISwitch :1个子视图
  • UITextView : 1 Subview UITextView :1个子视图
  • UIDatePicker : 1 Subview UIDatePicker :1个子视图
  • UITableView : 1 Subview UITableView :1个子视图
  • UISearchBar : 1 Subview UISearchBar :1个子视图
  • UIProgressView : 2 Subviews UIProgressView :2个子视图
  • UIStepper : 3 Subviews UIStepper :3个子视图

Elements that have no Subviews: 没有子视图的元素:

  • UISegmentedControl
  • UIPickerView
  • UITextField
  • UISlider
  • UIPageControl

Source Code used to get these results: 用于获得以下结果的源代码:

    let tableView        = UITableView()
    let pickerViewHere   = UIPickerView()
    let segmentedControl = UISegmentedControl()
    let textField        = UITextField()
    let slider           = UISlider()
    let switchUI         = UISwitch()
    let progressView     = UIProgressView()
    let pageControl      = UIPageControl()
    let stepper          = UIStepper()
    let textView         = UITextView()
    let datePicker       = UIDatePicker()
    let searchBar        = UISearchBar()


    print("switchUI has: (\(switchUI.subviews.count)) subviews")
    print("progressView has: (\(progressView.subviews.count)) subviews")
    print("stepper has: (\(stepper.subviews.count)) subviews")
    print("textView has: (\(textView.subviews.count)) subviews")
    print("datePicker has: (\(datePicker.subviews.count)) subviews")
    print("tableView has: (\(tableView.subviews.count)) subviews")
    print("segmentedControl has: (\(segmentedControl.subviews.count)) subviews")
    print("pickerViewHERE has: (\(pickerViewHere.subviews.count)) subviews")
    print("pickerView has: (\(pickerView.subviews.count)) subviews")
    print("searchBar has: (\(searchBar.subviews.count)) subviews")
    print("textField has: (\(textField.subviews.count)) subviews")
    print("slider has: (\(slider.subviews.count)) subviews")
    print("pageControl has: (\(pageControl.subviews.count)) subviews")

Apparently, in iOS 11, UIPickerView creates its subviews in its layoutSubviews method. 显然,在iOS 11中, UIPickerView在其layoutSubviews方法中创建其子视图。 Presumably the other views also create their subviews lazily. 大概其他视图也懒惰地创建了它们的子视图。

Test code: 测试代码:

import UIKit

class ViewController: UIViewController {
    let pickerView = MyPickerView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(pickerView)
        pickerView.frame = view.bounds
    }
}

class MyPickerView: UIPickerView {
    override func layoutSubviews() {
        print("before layoutSubviews: \(subviews.count)")
        super.layoutSubviews()
        print("after layoutSubviews: \(subviews.count)")
    }
}

Output: 输出:

before layoutSubviews: 0
after layoutSubviews: 3
before layoutSubviews: 3
after layoutSubviews: 3
before layoutSubviews: 3
after layoutSubviews: 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM