tutorial the programming lenguaje language apple ios swift

ios - the - view.traitCollection.horizontalSizeClass devolviendo undefined(0) en viewDidLoad



the swift programming language pdf (4)

Estoy usando un UITextView dentro de un UIPageViewController, y quiero determinar el tamaño de fuente en función de la clase de tamaño del dispositivo

La primera diapositiva de la vista de la página se carga en ViewDidLoad de esta manera ( 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 }

Y luego, en 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 }

El problema es que la primera diapositiva, a la que se llamó en viewDidLoad, siempre usa el tamaño de fuente en la cláusula "else".

Si view.traitCollection.horizontalSizeClass , para esa primera diapositiva, obtengo 0 ( UIUserInterfaceSizeClassUnspecified ), para las siguientes diapositivas, obtengo el tamaño correcto.

Intenté mover todo el elemento a "viewWillAppear", y luego a UIPageViewController le suceden cosas extrañas (una diapositiva adicional con el texto de tamaño incorrecto detrás de las otras diapositivas)


Descubrí que si utilizo el objeto traitCollection de la pantalla principal, en lugar de la vista actual, obtengo la clase de tamaño correcto:

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


El problema es que viewDidLoad es demasiado pronto para preguntar acerca de la colección de rasgos de una vista. Esto se debe a que la colección de rasgos de una vista es una característica adquirida de la jerarquía de vistas, el entorno en el que se encuentra. Pero en viewDidLoad , la vista no tiene entorno: todavía no está en la jerarquía de vistas. Se ha cargado , lo que significa que existe: el controlador de vista ahora tiene una vista. Pero aún no se ha colocado en la interfaz, y no se colocará en la interfaz hasta después de viewWillAppear: que aparece más adelante en la secuencia de eventos.

Sin embargo, el controlador de vista también tiene una colección de rasgos, y tiene un entorno: cuando se llama a viewDidLoad , el controlador de vista forma parte de la jerarquía del controlador de vista. Por lo tanto, la solución más simple (y correcta) es solicitar el traitCollection de self , no de view . Simplemente diga self.traitCollection donde ahora tiene view.traitCollection , y todo estará bien.

(Es posible que su solución, que solicita a la pantalla su colección de rasgos, funcione, pero no es confiable y no es el enfoque correcto. Esto se debe a que es posible que el controlador de vista principal altere la colección de caracteres de su hijo, y Si omite el enfoque correcto y pregunta directamente a la pantalla, no podrá obtener la colección de rasgos correcta.)


En mi caso, necesité mi opinión para saber sobre la clase de tamaño horizontal, por lo que acceder a la colección de rasgos UIScreen fue tentador pero no me animó, así que tuve algo como esto:

override func layoutSubviews() { super.layoutSubviews() print("/(self.traitCollection.horizontalSizeClass.rawValue)") switch self.traitCollection.horizontalSizeClass { case .regular: fontSize = 28 case .compact, .unspecified: 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() } }


Será mejor que mueva ese código al método viewWillAppear, ya que en viewDidLoad la vista de ViewController no se ha agregado a la jerarquía todavía, y es posible que obtenga una colección de rasgos vacía.