view.traitCollection.horizontalSizeClass在viewDidLoad中返回未定义的(



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

页面视图的第一张幻灯片加载在ViewDidLoad中,如下所示(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
}

然后,在视图ControllerAtIndex:中

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
}

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

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

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

问题是viewDidLoad询问视图的特征集合为时过早。这是因为视图的特征集合是从视图层次结构中获取的特征,即视图所在的环境。但在viewDidLoad中,视图有环境:它还不在视图层次结构中的中。它已加载,这意味着它存在:视图控制器现在具有视图。但它还没有被放入接口中,直到事件序列中较晚出现的viewDidAppear:才会被放入接口。

然而,视图控制器也有一个特征集合,并且它确实有一个环境:当调用viewDidLoad时,视图控制器已成为视图控制器层次结构的一部分。因此,最简单(也是正确的)的解决方案是要求selftraitCollection,而不是view。只要说self.traitCollection,你现在有了view.traitCollection,一切都会好起来的。

(你的解决方案,向屏幕询问其特征集合,可能会发生,但这是不可靠的,也不是正确的方法。这是因为父视图控制器有可能更改其子视图的特征集合,如果你绕过正确的方法,直接向屏幕询问,你将无法获得正确的特征集合。)

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

if (UIScreen.main.traitCollection.horizontalSizeClass == .compact) {
fontSize = "20"
} else {
fontSize = "28"
}

您最好将代码移动到viewWillAppear方法,因为在viewDidLoad中,ViewController的视图尚未添加到层次结构中,您可能会得到一个空的trait集合。

在我的案例中,我需要我的视图来了解horizontalSizeClass,所以访问UIScreen traitCollection很有吸引力,但并不鼓励,所以我有这样的东西:

override func layoutSubviews() {
super.layoutSubviews()
print("(self.traitCollection.horizontalSizeClass.rawValue)")
switch self.traitCollection.horizontalSizeClass {
case .regular, .unspecified:
fontSize = 28
case .compact:
fontSize = 20
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
print("(self.traitCollection.horizontalSizeClass.rawValue)")
guard let previousTraitCollection = previousTraitCollection else { return }
if self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass {
layoutIfNeeded()
}
}

我从这个苹果技术问答中得到了提示;用CCD_ 13代替CCD_ 14/CCD_。

最新更新