view.traitCollection.horizo​​ntalSizeClass在viewDidLoad中返回undefined(0)

coo*_*ita 19 ios swift

我在UIPageViewController中使用UITextView,我想根据设备的大小类确定字体大小.

页面视图的第一张幻灯片加载在ViewDidLoad中,如so(viewControllerAtIndex(0)):

override func viewDidLoad() {
    super.viewDidLoad()

    //Some unrelated code here

    // Page View Controller for Questions Slider
    questionPageVC = storyboard?.instantiateViewControllerWithIdentifier("QuestionPageView") as? UIPageViewController
    questionPageVC!.dataSource = self;
    questionPageVC!.delegate = self;

    let startingViewController : QuestionContentViewController = viewControllerAtIndex(0) as QuestionContentViewController
    var viewControllers = [startingViewController]

    questionPageVC!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)

    let sliderHeight = view.frame.size.height * 0.5
    questionPageVC!.view.frame = CGRectMake(20, 70,
     view.frame.size.width-40, sliderHeight)

    addChildViewController(questionPageVC!)
    view.addSubview(questionPageVC!.view!)
    questionPageVC?.didMoveToParentViewController(self)

    var pageControl : UIPageControl = UIPageControl.appearance()
    pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
    pageControl.currentPageIndicatorTintColor = UIColor.blackColor()
    pageControl.backgroundColor = UIColor.whiteColor()

    // Some more code here
}
Run Code Online (Sandbox Code Playgroud)

然后,在viewControllerAtIndex中:

private func viewControllerAtIndex(index: Int) -> QuestionContentViewController {
    var pcvc : QuestionContentViewController = storyboard?.instantiateViewControllerWithIdentifier("QuestionContentView") as! QuestionContentViewController

    var fontSize = ""

    if (view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
        fontSize = "20"
    } else {
        fontSize = "28"
    }

    pcvc.questionString = TextFormatter(string: fontSize + questionsArray[index]).formattedString
    pcvc.questionIndex = index

    return pcvc

}
Run Code Online (Sandbox Code Playgroud)

问题是在viewDidLoad中调用的第一张幻灯片始终使用"else"子句中的字体大小.

如果我打印view.traitCollection.horizontalSizeClass,对于第一张幻灯片,我得到0(UIUserInterfaceSizeClassUnspecified),对于后续幻灯片,我得到正确的大小.

我尝试将整个事情移动到"viewWillAppear",然后UIPageViewController发生奇怪的事情(在其他幻灯片后面有一个错误大小的文本的额外幻灯片)

mat*_*att 36

问题是,viewDidLoad要求查看视图的特征集合还为时过早.这是因为视图的特征集合是从视图层次结构中获取的特征,即它发现自身的环境.但是viewDidLoad,该视图有没有环境:它不是视图中的层次呢.它已加载,意味着它存在:视图控制器现在一个视图.但是它尚未被放入界面中,并且直到之后 viewWillAppear:的事件序列中才会被放入界面中.

但是,视图控制器也有一个特征集合,它确实有一个环境:在viewDidLoad调用时,视图控制器是视图控制器层次结构的一部分.因此最简单的(正确)的解决办法是索要traitCollectionself,不是的view.只要说出self.traitCollection你现在的位置view.traitCollection,一切都会好起来的.

(你的解决方案,询问屏幕的特征集合,可能会发生工作,但它不可靠,并且不是正确的方法.这是因为父视图控制器可以改变其子节点的特征集合,并且如果您绕过正确的方法并直接询问屏幕,您将无法获得正确的特征收集.)

  • 在引用视图控制器的特征集合时,我仍然会清除0,直到调用traitCollectionDidChange.只有在那之后我才有实际的大小类.这是一个视图控制器,它是页面视图控制器的一部分. (5认同)
  • @JeremyHicks 没错,视图控制器在拥有环境之前没有特征集合,即它是视图控制器层次结构的一部分。对于页面视图控制器,在您将其交给页面视图控制器之前,它不是视图控制器层次结构的一部分。 (2认同)

coo*_*ita 20

我发现如果我使用主屏幕的traitCollection而不是当前视图,我会得到正确的大小类:

if (UIScreen.main.traitCollection.horizontalSizeClass == .compact) {
    fontSize = "20"
} else {
    fontSize = "28"
}
Run Code Online (Sandbox Code Playgroud)