Guiones gráficos unificados en Xamarin. iOSUnified Storyboards in Xamarin.iOS

iOS 8 incluye un nuevo mecanismo más sencillo de usar para crear la interfaz de usuario, el guión gráfico unificado.iOS 8 includes a new, simpler-to-use mechanism for creating the user interface — the unified storyboard. Con un solo guión gráfico para cubrir todos los tamaños de pantalla de hardware diferentes, se pueden crear vistas rápidas y receptivas en un estilo de "diseño-una, uso-varios".With a single storyboard to cover all of the different hardware screen sizes, fast and responsive views can be created in a "design-once, use-many" style.

Como el desarrollador ya no necesita crear un guion gráfico independiente y específico para dispositivos iPhone e iPad, tiene la flexibilidad de diseñar aplicaciones con una interfaz común y, a continuación, personalizar esa interfaz para clases de tamaño diferentes.As the developer no longer needs to create a separate and specific storyboard for iPhone and iPad devices, they have the flexibility to design applications with a common interface and then customize that interface for different size classes. De esta manera, una aplicación se puede adaptar a las ventajas de cada factor de forma y cada interfaz de usuario se puede optimizar para proporcionar la mejor experiencia.In this way, an application can be adapted to the strengths of each form factor and each user interface can be tuned to provide the best experience.

Clases de tamañoSize Classes

Antes de iOS 8, el desarrollador usaba UIInterfaceOrientation y UIInterfaceIdiom para diferenciar entre los modos vertical y horizontal, y entre los dispositivos iPhone e iPad.Prior to iOS 8, the developer used UIInterfaceOrientation and UIInterfaceIdiom to differentiate between portrait and landscape modes, and between iPhone and iPad devices. En iOS8, la orientación y el dispositivo se determinan mediante el uso de clases de tamaño.In iOS8, orientation and device is determined is by using Size Classes.

Los dispositivos se definen mediante clases de tamaño, tanto en los ejes verticales como horizontales, y hay dos tipos de clases de tamaño en iOS 8:Devices are defined by Size Classes, in both vertical and horizontal axes, and there are two types of size classes in iOS 8:

  • Normal : se trata de un tamaño de pantalla grande (como un iPad) o un gadget que proporciona la impresión de un gran tamaño (por ejemplo, un UIScrollViewRegular – This is for either a large screen size (such as an iPad) or a gadget that gives the impression of a large size (such as a UIScrollView
  • Compacto : es para dispositivos más pequeños (por ejemplo, un iPhone).Compact – This is for smaller devices (such as an iPhone). Este tamaño tiene en cuenta la orientación del dispositivo.This size takes into account the orientation of the device.

Si se usan juntos los dos conceptos, el resultado es una cuadrícula de 2 x 2 que define los diferentes tamaños posibles que se pueden usar en las distintas orientaciones, como se puede ver en el diagrama siguiente:If the two concepts are used together, the result is a 2 x 2 grid that defines the different possible sizes that can be used in both the differing orientations, as seen in the following diagram:

El desarrollador puede crear un controlador de vista que use cualquiera de las cuatro posibilidades que daría como resultado diseños diferentes (como se muestra en los gráficos anteriores).The developer can create a View Controller that uses any of the four possibilities that would result in different layouts (as seen in the graphics above).

Clases de tamaño de iPadiPad Size Classes

El iPad, debido al tamaño, tiene un tamaño de clase normal para ambas orientaciones.The iPad, due to the size, has a regular class size for both orientations.

Clases de tamaño de iPhoneiPhone Size Classes

El iPhone tiene clases de tamaño diferentes en función de la orientación del dispositivo:The iPhone has different size classes based on the orientation of the device:

  • Cuando el dispositivo está en modo vertical, la pantalla tiene una clase compacta horizontalmente y normal verticalmenteWhen the device is in portrait mode, the screen has a compact class horizontally and regular vertically
  • Cuando el dispositivo está en modo horizontal, las clases de pantalla se invierten del modo vertical.When the device is in landscape mode, the screen classes are reversed from portrait mode.

Clases de tamaño de iPhone 6 PlusiPhone 6 Plus Size Classes

Los tamaños son los mismos que los de los iPhone anteriores cuando están en orientación vertical, pero diferentes en horizontal:The sizes are the same as the earlier iPhones when in portrait orientation, but different in landscape:

Dado que el iPhone 6 Plus tiene una pantalla lo suficientemente grande, puede tener una clase de tamaño de ancho normal en el modo horizontal.Because the iPhone 6 Plus has a large enough screen, it is able to have a Regular Width Size Class in the Landscape mode.

Compatibilidad con una nueva escala de pantallaSupport for a New Screen Scale

El iPhone 6 Plus usa una nueva pantalla de alta retina con un factor de escala de pantalla de 3,0 (tres veces la resolución de pantalla del iPhone original).The iPhone 6 Plus uses a new Retina HD display with a screen scale factor of 3.0 (three times the original iPhone screen resolution). Para proporcionar la mejor experiencia posible en estos dispositivos, incluya la nueva ilustración diseñada para esta escala de pantalla.To provide the best possible experience on these devices, include new artwork designed for this screen scale. En Xcode 6 y versiones posteriores, los catálogos de recursos pueden incluir imágenes en los tamaños 1x, 2x y 3x. simplemente agregue los recursos de imagen nuevos e iOS elegirá los activos correctos cuando se ejecute en un iPhone 6 Plus.In Xcode 6 and above, asset catalogs can include images at 1x, 2x, and 3x sizes; simply add the new image assets and iOS will choose the correct assets when running on an iPhone 6 Plus.

El comportamiento de carga de imágenes en iOS también reconoce un sufijo @3x en archivos de imagen.The image loading behavior in iOS also recognizes an @3x suffix on image files. Por ejemplo, si el desarrollador incluye un recurso de imagen (en diferentes resoluciones) en la agrupación de la aplicación con los siguientes nombres de archivo: MonkeyIcon.png, MonkeyIcon@2x.pngy MonkeyIcon@3x.png.For example, if the developer includes an image asset (at different resolutions) in the application's bundle with the following file names: MonkeyIcon.png, MonkeyIcon@2x.png, and MonkeyIcon@3x.png. En el iPhone 6 más, la imagen de MonkeyIcon@3x.png se usará automáticamente si el desarrollador carga una imagen con el código siguiente:On the iPhone 6 Plus the MonkeyIcon@3x.png image will be used automatically if the developer loads an image using the following code:

UIImage icon = UIImage.FromFile("MonkeyImage.png");

O bien, si asignan la imagen a un elemento de la interfaz de usuario mediante el diseñador de iOS como MonkeyIcon.png, se usará el MonkeyIcon@3x.png de forma automática en el iPhone 6 Plus.Or if they assign the image to a UI element using the iOS Designer as MonkeyIcon.png, the MonkeyIcon@3x.png will be used, again automatically, on the iPhone 6 Plus.

Pantallas de inicio dinámicoDynamic Launch Screens

El archivo de pantalla de inicio se muestra como una pantalla de presentación mientras se inicia una aplicación de iOS para proporcionar comentarios al usuario de que la aplicación se está iniciando realmente.The launch screen file is displayed as a splash screen while an iOS application is launching to provide feedback to the user that the app is actually starting-up. Antes de iOS 8, el desarrollador tendría que incluir varios Default.png recursos de imagen para cada tipo de dispositivo, orientación y resolución de pantalla en la que se ejecutaba la aplicación.Prior to iOS 8, the developer would have to include multiple Default.png image assets for each device type, orientation and screen resolution that the application would be running on.

Como novedad de iOS 8, el desarrollador puede crear un único archivo de .xib atómico en Xcode que use las clases de diseño y tamaño automáticos para crear una pantalla de inicio dinámico que funcione en todos los dispositivos, resoluciones y orientaciones.New to iOS 8, the developer can create a single, atomic .xib file in Xcode that uses Auto Layout and Size Classes to create a Dynamic Launch Screen that will work for every device, resolution and orientation. Esto no solo reduce la cantidad de trabajo necesario para que el desarrollador cree y mantenga todos los recursos de imagen necesarios, pero reduce el tamaño del paquete instalado de la aplicación.This not only reduces the amount of work required of the developer to create and maintain all the required image assets, but it reduces the size of the application's installed bundle.

RasgosTraits

Los rasgos son propiedades que se pueden usar para determinar cómo cambia un diseño a medida que cambia su entorno.Traits are properties that can be used to determine how a layout changes as its environment changes. Están formados por un conjunto de propiedades (el HorizontalSizeClass y VerticalSizeClass basados en UIUserInterfaceSizeClass), así como la expresión de interfaz (UIUserInterfaceIdiom) y la escala de presentación.They consist of a set of properties (the HorizontalSizeClass and VerticalSizeClass based on UIUserInterfaceSizeClass), as well as the interface idiom ( UIUserInterfaceIdiom) and the display scale.

Todos los Estados anteriores se incluyen en un contenedor al que Apple hace referencia como una colección de rasgos (UITraitCollection), que no solo contiene las propiedades, sino también sus valores.All of the above states are wrapped up in a container that Apple refers to as a Trait Collection ( UITraitCollection), which contains not only the properties but their values as well.

Entorno de rasgosTrait Environment

Los entornos de rasgos son una nueva interfaz de iOS 8 y pueden devolver una colección de rasgos para los objetos siguientes:Trait Environments are a new interface in iOS 8 and are able to return a Trait Collection for the following objects:

  • Pantallas (UIScreens).Screens ( UIScreens ).
  • Windows (UIWindows).Windows ( UIWindows ).
  • Controladores de vista (UIViewController).View Controllers ( UIViewController ).
  • Vistas (UIView).Views ( UIView ).
  • Controlador de presentación (UIPresentationController).Presentation Controller ( UIPresentationController ).

El desarrollador utiliza la colección de rasgos devuelta por un entorno de rasgos para determinar cómo se debe diseñar una interfaz de usuario.The developer uses the Trait Collection returned by a Trait Environment to determine how a user interface should be laid out.

Todos los entornos de rasgos hacen que una jerarquía se vea en el diagrama siguiente:All of the Trait Environments make a hierarchy as seen in the following diagram:

La colección de rasgos que cada uno de los entornos de rasgo anteriores debe fluir, de forma predeterminada, del entorno primario al secundario.The Trait Collection that each of the above Trait Environments have will flow, by default, from the parent to the child environment.

Además de obtener la colección de rasgos actual, el entorno de rasgos tiene un método TraitCollectionDidChange, que se puede invalidar en las subclases del controlador de vista o vista.In addition to getting the current Trait Collection, the Trait Environment has a TraitCollectionDidChange method, which can be overridden in the View or View Controller subclasses. El desarrollador puede usar este método para modificar cualquiera de los elementos de la interfaz de usuario que dependen de rasgos cuando esos rasgos han cambiado.The developer can use this method to modify any of the UI elements that depend on traits when those traits have changed.

Colecciones de rasgos típicasTypical Trait Collections

En esta sección se tratarán los tipos típicos de colecciones de rasgos que el usuario experimentará al trabajar con iOS 8.This section will cover the typical types of trait collections that the user will experience when working with iOS 8.

A continuación se muestra una colección de rasgos típica que el desarrollador podría ver en un iPhone:The following is a typical Trait Collection that the developer might see on an iPhone:

PropertyProperty ValorValue
HorizontalSizeClass CompactCompact
VerticalSizeClass EstándarRegular
UserInterfaceIdom TeléfonoPhone
DisplayScale 2.02.0

El conjunto anterior representaría una colección de rasgos completa, ya que tiene valores para todas sus propiedades de rasgo.The above set would represent a Fully Qualified Trait Collection, as it has values for all of its trait properties.

También es posible tener una colección de rasgos que no presente algunos de sus valores (a los que Apple hace referencia como no especificado):It is also possible to have a Trait Collection that is missing some of its values (which Apple refers to as Unspecified):

PropertyProperty ValorValue
HorizontalSizeClass CompactCompact
VerticalSizeClass Sin especificarUnspecified
UserInterfaceIdom Sin especificarUnspecified
DisplayScale Sin especificarUnspecified

Sin embargo, por lo general, cuando el desarrollador solicita el entorno de rasgo para su colección de rasgos, devolverá una colección completa como se mostró en el ejemplo anterior.Generally, however, when the developer asks the Trait Environment for its Trait Collection, it will return a fully qualified collection as seen in the example above.

Si un entorno de rasgos (por ejemplo, un controlador de vista o vista) no se encuentra dentro de la jerarquía de vistas actual, el desarrollador podría obtener los valores no especificados para una o varias de las propiedades de rasgo.If a Trait Environment (like a View or View Controller) is not inside of the current view hierarchy, the developer might get back unspecified values for one or more of the trait properties.

El desarrollador también obtendrá una colección de rasgos parcialmente cualificada si usa uno de los métodos de creación proporcionados por Apple, como UITraitCollection.FromHorizontalSizeClass, para crear una nueva colección.The developer will also get a partially qualified Trait Collection if they use one of the creation methods provided by Apple, such as UITraitCollection.FromHorizontalSizeClass, to create a new collection.

Una operación que se puede realizar en varias colecciones de rasgos se compara entre sí, lo que implica la pregunta de una colección de rasgos si contiene otra.One operation that can be performed on multiple Trait Collections is comparing them to each other, which involves asking one Trait Collection if it contains another one. Lo que significa la contención es que, para cualquier rasgo especificado en la segunda colección, el valor debe coincidir exactamente con el valor de la primera colección.What is meant by Containment is that, for any trait specified in the second collection, the value must match exactly with the value in the first collection.

Para probar dos rasgos, use el método Contains del UITraitCollection pasando el valor del rasgo que se va a probar.To test two traits use the Contains method of the UITraitCollection passing in the value of the trait to be tested.

El desarrollador puede realizar las comparaciones manualmente en el código para determinar cómo diseñar vistas o controladores de vistas.The developer can perform the comparisons manually in code to determine how to layout Views or View Controllers. Sin embargo, UIKit usa este método internamente para proporcionar parte de su funcionalidad, como en el proxy de apariencia, por ejemplo.However, UIKit uses this method internally to provide some of its functionality, as in the Appearance Proxy, for example.

Proxy de aparienciaAppearance Proxy

El proxy de apariencia se presentó en versiones anteriores de iOS para que los desarrolladores puedan personalizar las propiedades de sus vistas.The Appearance Proxy was introduced in earlier versions of iOS to allow developers to customize the properties of their Views. Se ha ampliado en iOS 8 para admitir colecciones de rasgos.It has been extended in iOS 8 to support Trait Collections.

Los proxies de apariencia ahora incluyen un nuevo método, AppearanceForTraitCollection, que devuelve un nuevo proxy de apariencia para la colección de rasgos especificada que se ha pasado.Appearance Proxies now include a new method, AppearanceForTraitCollection, that returns a new Appearance Proxy for the given Trait Collection that has been passed in. Las personalizaciones que realice el desarrollador en ese proxy de apariencia solo surtirán efecto en las vistas que se ajusten a la colección de rasgos especificada.Any customizations that the developer performs on that Appearance Proxy will only take effect on Views that conform to the specified Trait Collection.

Por lo general, el desarrollador pasará una colección de rasgos especificada parcialmente al método AppearanceForTraitCollection, como uno que acaba de especificar una clase de tamaño horizontal de Compact, de modo que podría personalizar cualquier vista de la aplicación que esté compactada horizontalmente.Generally the developer will pass in a partially specified Trait Collection to the AppearanceForTraitCollection method, such as one that just specified a Horizontal Size Class of Compact, so that they could customize any view in the application that is compact horizontally.

UIImageUIImage

Otra clase a la que Apple ha agregado la colección de rasgos es UIImage.Another class that Apple has added Trait Collection to is UIImage. En el pasado, el desarrollador tenía que especificar un @1X y @2x versión de cualquier recurso gráfico de mapa de que se iba a incluir en la aplicación (por ejemplo, un icono).In the past the developer had to specify a @1X and @2x version of any bitmapped graphic asset that they were going to include in the application (such as an icon).

iOS 8 se ha ampliado para permitir que el desarrollador incluya varias versiones de una imagen en un catálogo de imágenes basado en una colección de rasgos.iOS 8 has been expanded to allow the developer to include multiple version of an image in an Image Catalog based on a Trait Collection. Por ejemplo, el desarrollador podría incluir una imagen más pequeña para trabajar con una clase de rasgo compacto y una imagen de tamaño completo para cualquier otra colección.For example, the developer could include a smaller image for working with a Compact Trait Class and a full sized image for any other collection.

Cuando una de las imágenes se usa dentro de una clase UIImageView, la vista de imagen mostrará automáticamente la versión correcta de la imagen para su colección de rasgos.When one of the images is used inside of a UIImageView class, the Image View will automatically display the correct version of the image for its Trait Collection. Si el entorno de rasgo cambia (por ejemplo, el usuario que cambia el dispositivo de vertical a horizontal), la vista de imagen seleccionará automáticamente el nuevo tamaño de la imagen para que coincida con la nueva colección de rasgos y cambiará su tamaño para que coincida con el de la versión actual de la imagen. indica.If the Trait Environment changes (such as the user switching the device from portrait to landscape), the Image View will automatically select the new image size to match the new Trait Collection and change its size to match that of the current version of the image being displayed.

UIImageAssetUIImageAsset

Apple ha agregado una nueva clase a iOS 8 llamada UIImageAsset para ofrecer al desarrollador aún más control sobre la selección de imágenes.Apple has added a new class to iOS 8 called UIImageAsset to give the developer even more control over image selection.

Un recurso de imagen incluye todas las distintas versiones de una imagen y permite al desarrollador solicitar una imagen específica que coincida con una colección de rasgos que se ha pasado.An Image Asset wraps up all of the different versions of an image and allows the developer to ask for a specific image that matches a Trait Collection that has been passed in. Las imágenes se pueden agregar o quitar de un recurso de imagen, sobre la marcha.Images can be added or removed from an Image Asset, on-the-fly.

Para obtener más información sobre los recursos de imagen, vea la documentación de UIImageAsset de Apple.For more information on Image Assets, see Apple's UIImageAsset documentation.

Combinar colecciones de rasgosCombining Trait Collections

Otra función que puede realizar un programador en las colecciones de rasgos es agregar dos juntos que darán como resultado la colección combinada, donde los valores no especificados de una colección se reemplazan por los valores especificados en un segundo.Another function that a developer can perform on Trait Collections is to add two together that will result in the combined collection, where the unspecified values from one collection are replaced by the specified values in a second one. Esto se hace mediante el método FromTraitsFromCollections de la clase UITraitCollection.This is done using the FromTraitsFromCollections method of the UITraitCollection class.

Como se indicó anteriormente, si alguno de los rasgos no está especificado en una de las colecciones de rasgos y se especifica en otro, el valor se establecerá en la versión especificada.As stated above, if any of the traits is unspecified in one of the Trait Collections and is specified in another, the value will be set to the specified version. Sin embargo, si se especifican varias versiones de un valor determinado, el valor de la última colección de rasgos será el valor que se utiliza.However, if there are multiple versions of a given value specified, the value from the last Trait Collection will be the value that is used.

Controladores de vistas adaptablesAdaptive View Controllers

En esta sección se explican los detalles de cómo los controladores de vista y vista de iOS han adoptado los conceptos de rasgos y clases de tamaño para ser más adaptables de forma automática en las aplicaciones del desarrollador.This section will cover the details of how the iOS View and View Controllers have adopted the concepts of Traits and Size Classes to automatically be more adaptive in the developer's applications.

Controlador de vista en dos panelesSplit View Controller

Una de las clases de controlador de vista que ha cambiado más en iOS 8 es la clase UISplitViewController.One of the View Controller classes that has changed the most in iOS 8 is the UISplitViewController class. En el pasado, el desarrollador solía usar un controlador de vista dividida en la versión de iPad de la aplicación y, a continuación, tendría que proporcionar una versión completamente diferente de la jerarquía de vistas para la versión de iPhone de la aplicación.In the past, the developer would often use a Split View Controller on the iPad version of the application and then they would have to provide a completely different version of their view hierarchy for the iPhone version of the app.

En iOS 8, la clase UISplitViewController está disponible en ambas plataformas (iPad y iPhone), lo que permite al desarrollador crear una jerarquía de controlador de vista que funcionará para iPhone y iPad.In iOS 8, the UISplitViewController class is available on both platforms (iPad and iPhone), which allows the developer to create one View Controller hierarchy that will function for both iPhone and iPad.

Cuando un iPhone está en horizontal, el controlador de vista en dos paneles presenta sus vistas en paralelo, tal como lo haría en un iPad.When an iPhone is in Landscape, the Split View Controller will present its Views side-by-side, just as it would when being displayed on an iPad.

Invalidar rasgosOverriding Traits

Los entornos de rasgos se colocan en cascada desde el contenedor principal hasta los contenedores secundarios, como en el siguiente gráfico que muestra un controlador de vista en dos paneles en un iPad con la orientación horizontal:Trait Environments cascade from the parent container down to the child containers, as in the following graphic showing a Split View Controller on an iPad in the landscape orientation:

Dado que el iPad tiene una clase de tamaño normal en las orientaciones horizontal y vertical, la vista en dos paneles mostrará las vistas principal y de detalle.Since the iPad has a Regular Size Class in both the horizontal and vertical orientations, the Split View will display both the master and detail views.

En un iPhone, donde la clase de tamaño es compacta en ambas orientaciones, el controlador de vista en dos paneles solo muestra la vista de detalle, como se muestra a continuación:On an iPhone, where the Size Class is compact in both orientations, the Split View Controller only displays the detail view, as seen below:

En una aplicación en la que el desarrollador desea mostrar tanto la vista maestra como la vista de detalle en un iPhone con la orientación horizontal, el desarrollador debe insertar un contenedor primario para el controlador de vista en dos paneles e invalidar la colección de rasgos.In an application where the developer wants to display both the master and detail view on an iPhone in the landscape orientation, the developer must insert a parent container for the Split View Controller and override the Trait Collection. Tal como se muestra en el siguiente gráfico:As seen in the graphic below:

Un UIView se establece como el elemento primario del controlador de vista en dos paneles y se llama al método SetOverrideTraitCollection en la vista que pasa una nueva colección de rasgos y que tiene como destino el controlador de vista de división.A UIView is set as the parent of the Split View Controller and the SetOverrideTraitCollection method is called on the view passing in a new Trait Collection and targeting the Split View Controller. La nueva colección de rasgos invalida el HorizontalSizeClass, estableciéndolo en Regular, de modo que el controlador de vista en dos paneles muestre las vistas principal y de detalle en un iPhone en la orientación horizontal.The new Trait Collection overrides the HorizontalSizeClass, setting it to Regular, so that the Split View Controller will display both the master and detail views on an iPhone in the landscape orientation.

Tenga en cuenta que el VerticalSizeClass se estableció en unspecified, lo que permite agregar la nueva colección de rasgos a la colección de rasgos en el elemento primario, lo que da lugar a un Compact VerticalSizeClass para el controlador de vista dividida secundaria.Note that the VerticalSizeClass was set to unspecified, which allows the new Trait Collection to be added to the Trait Collection on the parent, resulting in a Compact VerticalSizeClass for the child Split View Controller.

Cambios de rasgoTrait Changes

En esta sección se examinan, en detalle, el modo en que las colecciones de rasgos pasan cuando cambia el entorno de rasgo.This section will take a look, in detail, at how the Trait Collections transition when the Trait Environment changes. Por ejemplo, cuando el dispositivo se gira de vertical a horizontal.For example, when the device is rotated from portrait to landscape.

En primer lugar, iOS 8 realiza alguna configuración para preparar la transición.First, iOS 8 does some setup to prepare for the transition to take place. A continuación, el sistema anima el estado de transición.Next, the system animates the transition state. Por último, iOS 8 limpia todos los Estados temporales necesarios durante la transición.Finally, iOS 8 cleans-up any temporary states required during the transition.

iOS 8 proporciona varias devoluciones de llamada que el desarrollador puede usar para participar en el cambio de rasgo, tal como se muestra en la tabla siguiente:iOS 8 provides several callbacks that the developer can use to participate in the Trait Change as seen in the following table:

PhasePhase CallbackCallback DescriptionDescription
Programa de instalaciónSetup
  • WillTransitionToTraitCollection
  • TraitCollectionDidChange
  • Se llama a este método al principio de un cambio de rasgo antes de que una colección de rasgos se establezca en su nuevo valor.This method gets called at the beginning of a Trait Change before a Trait Collection gets set to its new value.
  • Se llama al método cuando el valor de la colección de rasgos ha cambiado pero antes de que tenga lugar cualquier animación.The method gets called when the value of the Trait Collection has changed but before any animation takes place.
AnimaciónAnimation WillTransitionToTraitCollection El Coordinador de transiciones que se pasa a este método tiene una propiedad AnimateAlongside que permite al desarrollador agregar animaciones que se ejecutarán junto con las animaciones predeterminadas.The Transition Coordinator that gets passed to this method has an AnimateAlongside property that allows the developer to add animations that will be executed along with the default animations.
LimpiezaClean-up WillTransitionToTraitCollection Proporciona un método para que los desarrolladores incluyan su propio código de limpieza después de que tenga lugar la transición.Provides a method for developers to include their own cleanup code after the transition takes place.

El método WillTransitionToTraitCollection es ideal para animar los controladores de vista junto con los cambios en la colección de rasgos.The WillTransitionToTraitCollection method is great for animating View Controllers along with the Trait Collection changes. El método WillTransitionToTraitCollection solo está disponible en los controladores de vista (UIViewController) y no en otros entornos de rasgo, como UIViews.The WillTransitionToTraitCollection method is only available on View Controllers ( UIViewController) and not on other Trait Environments, like UIViews.

La TraitCollectionDidChange es excelente para trabajar con la clase UIView, donde el desarrollador desea actualizar la interfaz de usuario a medida que los rasgos cambian.The TraitCollectionDidChange is great for working with the UIView class, where the developer wants to update the UI as the traits are changing.

Contraer los controladores de vista en dos panelesCollapsing the Split View Controllers

Ahora veamos más detenidamente lo que ocurre cuando un controlador de vista en dos paneles se contrae de una columna en una vista de una columna.Now let's take a closer look at what happens when a Split View Controller collapses from a two column to a one column view. Como parte de este cambio, hay dos procesos que deben realizarse:As part of this change, there are two processes that need to occur:

  • De forma predeterminada, el controlador de vista en dos paneles usará el controlador de vista principal como vista después de que se produzca la contracción.By default, the Split View Controller will use the primary view controller as the view after the collapse occurs. El desarrollador puede invalidar este comportamiento invalidando el método GetPrimaryViewControllerForCollapsingSplitViewController del UISplitViewControllerDelegate y proporcionando cualquier controlador de vista que desee mostrar en el estado contraído.The developer can override this behavior by overriding the GetPrimaryViewControllerForCollapsingSplitViewController method of the UISplitViewControllerDelegate and providing any View Controller that they want to display in the collapsed state.
  • El controlador de vista secundario tiene que combinarse en el controlador de vista principal.The Secondary View Controller has to get merged into the Primary View Controller. Por lo general, el desarrollador no tendrá que realizar ninguna acción para este paso; el controlador de vista en dos paneles incluye el control automático de esta fase basándose en el dispositivo de hardware.Generally the developer will not need to take any action for this step; the Split View Controller includes automatic handling of this phase based on the hardware device. Sin embargo, puede haber algunos casos especiales en los que el desarrollador desee interactuar con este cambio.However, there may be some special cases where the developer will want to interact with this change. La llamada al método CollapseSecondViewController del UISplitViewControllerDelegate permite mostrar el controlador de vista principal cuando se produce la contracción, en lugar de la vista de detalles.Calling the CollapseSecondViewController method of the UISplitViewControllerDelegate allows the master view controller to be displayed when the collapse occurs, instead of the details view.

Expandir el controlador de vista en dos panelesExpanding the Split View Controller

Ahora veamos más detenidamente lo que ocurre cuando un controlador de vista en dos paneles se expande desde un estado contraído.Now let's take a closer look at what happens when a Split View Controller is expanded from a collapsed state. Una vez más, hay dos fases que deben producirse:Once again, there are two stages that need to occur:

  • En primer lugar, defina el nuevo controlador de vista principal.First, define the new Primary View Controller. De forma predeterminada, el controlador de vista en dos paneles usará automáticamente el controlador de vista principal de la vista contraída.By default, the Split View Controller will automatically use the Primary View Controller from the collapsed view. De nuevo, el desarrollador puede invalidar este comportamiento mediante el método GetPrimaryViewControllerForExpandingSplitViewController de la UISplitViewControllerDelegate.Again, the developer can override this behavior using the GetPrimaryViewControllerForExpandingSplitViewController method of the UISplitViewControllerDelegate .
  • Una vez elegido el controlador de vista principal, se debe volver a crear el controlador de vista secundario.Once the Primary View Controller has been chosen, the Secondary View Controller must be recreated. De nuevo, el controlador de vista en dos paneles incluye el control automático de esta fase basándose en el dispositivo de hardware.Again, the Split View Controller includes automatic handling of this phase based on the hardware device. El desarrollador puede invalidar este comportamiento llamando al método SeparateSecondaryViewController del UISplitViewControllerDelegate.The developer can override this behavior by calling the SeparateSecondaryViewController method of the UISplitViewControllerDelegate .

En un controlador de vista en dos paneles, el controlador de vista principal juega una parte en la expansión y la contracción de las vistas mediante la implementación de los métodos CollapseSecondViewController y SeparateSecondaryViewController de la UISplitViewControllerDelegate.In a Split View Controller, the Primary View Controller plays a part in both the expanding and collapsing of the views by implementing the CollapseSecondViewController and SeparateSecondaryViewController methods of the UISplitViewControllerDelegate. UINavigationController implementa estos métodos para enviar y extraer automáticamente el controlador de vista secundario.UINavigationController implements these methods to automatically push and pop the Secondary View controller.

Mostrar controladores de vistaShowing View Controllers

Otro cambio que Apple ha realizado en iOS 8 es la forma en que el desarrollador muestra los controladores de vista.Another change that Apple has made to iOS 8 is in the way that the developer shows View Controllers. En el pasado, si la aplicación tuviera un controlador de vista hoja (por ejemplo, un controlador de vista de tabla) y el desarrollador mostrase un diferente (por ejemplo, en respuesta al punteo del usuario en una celda), la aplicación volvería a través de la jerarquía del controlador hasta el controlador de vista de navegación y llamará al método PushViewController para mostrar la nueva vista.In the past, if the application had a Leaf View Controller (such as a Table View Controller), and the developer showed a different one (for example, in response to the user tapping on a cell), the application would reach back through the controller hierarchy to the Navigation View Controller and call the PushViewController method against it to display the new view.

Esto presentó un acoplamiento muy estrecho entre el controlador de navegación y el entorno en el que se estaba ejecutando.This presented a very tight coupling between the Navigation Controller and the environment that it was running in. En iOS 8, Apple ha desacoplado esto proporcionando dos nuevos métodos:In iOS 8, Apple has decoupled this by providing two new methods:

  • ShowViewController: se adapta para mostrar el nuevo controlador de vista en función de su entorno.ShowViewController – Adapts to display the new view controller based on its environment. Por ejemplo, en una UINavigationController simplemente se envía la nueva vista en la pila.For example, in a UINavigationController it simply pushes the new view onto the stack. En un controlador de vista en dos paneles, el nuevo controlador de vista se presentará en el lado izquierdo como el nuevo controlador de vista principal.In a Split View Controller, the new View Controller will be presented on the left side as the new Primary View Controller. Si no hay ningún controlador de vista de contenedor, la nueva vista se mostrará como un controlador de vista modal.If no container view controller is present, the new view will be displayed as a Modal View Controller.
  • ShowDetailViewController: funciona de manera similar a ShowViewController, pero se implementa en un controlador de vista en dos paneles para reemplazar la vista de detalles con el nuevo controlador de vistas que se pasa.ShowDetailViewController – Works in a similar fashion to ShowViewController, but is implemented on a Split View Controller to replace the details view with the new View Controller being passed in. Si el controlador de vista en dos paneles está contraído (como podría verse en una aplicación de iPhone), la llamada se redirigirá al método ShowViewController y la nueva vista se mostrará como el controlador de vista principal.If the Split View Controller is collapsed (as might be seen in an iPhone Application), the call will be redirected to the ShowViewController method, and the new view will be shown as the Primary View Controller. De nuevo, si no hay ningún controlador de vista de contenedor, la nueva vista se mostrará como un controlador de vista modal.Again, if no container view controller is present, the new view will be displayed as a Modal View Controller.

Estos métodos funcionan empezando por el controlador de vista Hoja y pasando por la jerarquía de vistas hasta que encuentren el controlador de vista del contenedor adecuado para controlar la presentación de la nueva vista.These methods work by starting at the Leaf View Controller and walk up the view hierarchy until they find the right container view controller to handle the display of the new view.

Los desarrolladores pueden implementar ShowViewController y ShowDetailViewController en sus propios controladores de vista personalizados para obtener la misma funcionalidad automatizada que proporcionan UINavigationController y UISplitViewController.Developers can implement ShowViewController and ShowDetailViewController in their own custom View Controllers to get the same automated functionality that UINavigationController and UISplitViewController provides.

FuncionamientoHow it works

En esta sección, echaremos un vistazo a cómo se implementan realmente estos métodos en iOS 8.In this section we will take a look at how these methods are actually implemented in iOS 8. En primer lugar, echemos un vistazo al nuevo método GetTargetForAction:First let’s look at the new GetTargetForAction method:

Este método recorre la cadena de jerarquía hasta que se encuentra el controlador de vista del contenedor correcto.This method walks the hierarchy chain until the correct container view controller is found. Por ejemplo:For example:

  1. Si se llama a un método de ShowViewController, el primer controlador de vista de la cadena que implementa este método es el controlador de navegación, por lo que se usa como elemento primario de la nueva vista.If a ShowViewController method is called, the first View Controller in the chain that implements this method is the Navigation Controller, so it is used as the parent of the new view.
  2. Si en su lugar se llama a un método ShowDetailViewController, el controlador de vista en dos paneles es el primer controlador de vista para implementarlo, por lo que se usa como elemento primario.If a ShowDetailViewController method was called instead, the Split View Controller is the first View Controller to implement it, so it is used as the parent.

El método GetTargetForAction funciona localizando un controlador de vistas que implementa una acción determinada y, a continuación, solicitando a ese controlador de vista si desea recibir esa acción.The GetTargetForAction method works by locating a View Controller that implements a given Action and then asking that View Controller if it wants to receive that action. Dado que este método es público, los desarrolladores pueden crear sus propios métodos personalizados que funcionen igual que los métodos integrados ShowViewController y ShowDetailViewController.Since this method is public, developers can create their own custom methods that function just like the built in ShowViewController and ShowDetailViewController methods.

Presentación adaptableAdaptive Presentation

En iOS 8, Apple ha realizado también la adaptación de las presentaciones de elemento flotante (UIPopoverPresentationController).In iOS 8, Apple has made Popover Presentations ( UIPopoverPresentationController) adaptive as well. Por lo tanto, un controlador de vista de presentación de elemento flotante presentará automáticamente una vista de elemento flotante normal en una clase de tamaño normal, pero la mostrará en una clase de tamaño compacta horizontalmente (por ejemplo, en un iPhone).So a Popover Presentation View Controller will automatically present a normal Popover View in a Regular Size Class, but will display it full screen in a horizontally compact Size Class (such as on an iPhone).

Para dar cabida a los cambios en el sistema de guion gráfico unificado, se ha creado un nuevo objeto de controlador para administrar los controladores de vista presentados: UIPresentationController.To accommodate the changes within the unified storyboard system, a new controller object has been created to manage the presented View Controllers — UIPresentationController. Este controlador se crea a partir del momento en que se presenta el controlador de vista hasta que se descarta.This controller is created from the time the View Controller is presented until it is dismissed. Como es una clase de administración, se puede considerar una superclase sobre el controlador de vista a medida que responde a los cambios del dispositivo que afectan al controlador de vistas (como la orientación), que luego se devuelven al controlador de la vista que el controlador de presentación controla.As it is a managing class, it can be considered a super class over the View Controller as it responds to device changes that affect the View Controller (such as orientation) which are then fed back into the View Controller the Presentation Controller controls.

Cuando el desarrollador presenta un controlador de vista con el método PresentViewController, la administración del proceso de presentación se entrega a UIKit.When the developer presents a View Controller using the PresentViewController method, the management of the presentation process is handed to UIKit. UIKit controla (entre otras cosas) el controlador correcto para el estilo que se está creando, con la única excepción cuando un controlador de vista tiene el estilo establecido en UIModalPresentationCustom.UIKit handles (among other things) the correct controller for the style being created, with the only exception being when a View Controller has the style set to UIModalPresentationCustom. Aquí, la aplicación puede proporcionar su propio PresentationController en lugar de usar el controlador de UIKit.Here, the application can provide it’s own PresentationController rather than using the UIKit controller.

Estilos de presentación personalizadosCustom Presentation Styles

Con un estilo de presentación personalizado, los desarrolladores tienen la opción de usar un controlador de presentación personalizado.With a custom presentation style, developers have the option to use a custom Presentation Controller. Este controlador personalizado se puede usar para modificar la apariencia y el comportamiento de la vista a la que es Allied.This custom controller can be used to modify the appearance and behavior of the View it is allied to.

Trabajar con clases de tamañoWorking with Size Classes

El proyecto Adaptive photos de Xamarin que se incluye en este artículo ofrece un ejemplo práctico del uso de clases de tamaño y controladores de vistas adaptables en una aplicación de interfaz unificada de iOS 8.The Adaptive Photos Xamarin Project that is included with this article gives a working example of using Size Classes and Adaptive View Controllers in an iOS 8 Unified Interface application.

Mientras que la aplicación crea su interfaz de usuario completamente a partir del código, en lugar de usar el diseñador de IOS y crear un guión gráfico unificado, se aplican las mismas técnicas.While the application creates its UI completely from code, as opposed to using the IOS Designer and creating a Unified Storyboard, the same techniques apply. Más adelante en este artículo, le mostraremos cómo usar clases de tamaño con un guión gráfico unificado y el diseñador de iOS en una aplicación de Xamarin.Later in this article, we’ll show how to use Size Classes with a Unified Storyboard and the iOS Designer in a Xamarin Application.

Ahora, echemos un vistazo más de cerca a cómo el proyecto Adaptive photos está implementando algunas de las características de la clase size en iOS 8 para crear una aplicación adaptable.Now let’s take a closer look at how the Adaptive Photos project is implementing several of the Size Class features in iOS 8 to create a Adaptive Application.

Adaptación a los cambios en el entorno de rasgoAdapting to Trait Environment Changes

Cuando se ejecuta la aplicación Adaptive photos en un iPhone, cuando el usuario gira el dispositivo de vertical a horizontal, el controlador de vista en dos paneles muestra la vista de maestro y detalles:When running the Adaptive Photos application on an iPhone, when the user rotates the device from portrait to landscape, the Split View Controller will display both the master and details view:

Esto se logra invalidando el método UpdateConstraintsForTraitCollection del controlador de vista y ajustando las restricciones en función del valor de la VerticalSizeClass.This is accomplished by overriding the UpdateConstraintsForTraitCollection method of the View Controller and adjusting the constraints based on the value of the VerticalSizeClass. Por ejemplo:For example:

public void UpdateConstraintsForTraitCollection (UITraitCollection collection)
{
    var views = NSDictionary.FromObjectsAndKeys (
        new object[] { TopLayoutGuide, ImageView, NameLabel, ConversationsLabel, PhotosLabel },
        new object[] { "topLayoutGuide", "imageView", "nameLabel", "conversationsLabel", "photosLabel" }
    );

    var newConstraints = new List<NSLayoutConstraint> ();
    if (collection.VerticalSizeClass == UIUserInterfaceSizeClass.Compact) {
        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]-[nameLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[conversationsLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[photosLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide][imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.Add (NSLayoutConstraint.Create (ImageView, NSLayoutAttribute.Width, NSLayoutRelation.Equal,
            View, NSLayoutAttribute.Width, 0.5f, 0.0f));
    } else {
        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[nameLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[conversationsLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[photosLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]-20-[imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
    }

    if (constraints != null)
        View.RemoveConstraints (constraints.ToArray ());

    constraints = newConstraints;
    View.AddConstraints (constraints.ToArray ());
}

Agregar animaciones de transiciónAdding Transition Animations

Cuando el controlador de vista en dos paneles de la aplicación fotos adaptables pasa de contraído a expandido, las animaciones se agregan a las animaciones predeterminadas invalidando el método WillTransitionToTraitCollection del controlador de vista.When the Split View Controller in the Adaptive Photos application goes from collapsed to expanded, animations are added to the default animations by overriding the WillTransitionToTraitCollection method of the view controller. Por ejemplo:For example:

public override void WillTransitionToTraitCollection (UITraitCollection traitCollection, IUIViewControllerTransitionCoordinator coordinator)
{
    base.WillTransitionToTraitCollection (traitCollection, coordinator);
    coordinator.AnimateAlongsideTransition ((UIViewControllerTransitionCoordinatorContext) => {
        UpdateConstraintsForTraitCollection (traitCollection);
        View.SetNeedsLayout ();
    }, (UIViewControllerTransitionCoordinatorContext) => {
    });
}

Invalidar el entorno de rasgosOverriding the Trait Environment

Como se muestra arriba, la aplicación de fotos adaptables obliga al controlador de vista en dos paneles a mostrar los detalles y las vistas maestras cuando el dispositivo iPhone está en la vista horizontal.As show above, the Adaptive Photos application forces the Split View Controller to display both the details and the master views when the iPhone device is in the landscape view.

Esto se logra mediante el uso del código siguiente en el controlador de vista:This was accomplished by using the following code in the View Controller:

private UITraitCollection forcedTraitCollection = new UITraitCollection ();
...

public UITraitCollection ForcedTraitCollection {
    get {
        return forcedTraitCollection;
    }

    set {
        if (value != forcedTraitCollection) {
            forcedTraitCollection = value;
            UpdateForcedTraitCollection ();
        }
    }
}
...

public override void ViewWillTransitionToSize (SizeF toSize, IUIViewControllerTransitionCoordinator coordinator)
{
    ForcedTraitCollection = toSize.Width > 320.0f ?
         UITraitCollection.FromHorizontalSizeClass (UIUserInterfaceSizeClass.Regular) :
         new UITraitCollection ();

    base.ViewWillTransitionToSize (toSize, coordinator);
}

public void UpdateForcedTraitCollection ()
{
    SetOverrideTraitCollection (forcedTraitCollection, viewController);
}

Expandir y contraer el controlador de vista en dos panelesExpanding and Collapsing the Split View Controller

A continuación, vamos a examinar cómo se ha implementado el comportamiento de expansión y contracción del controlador de vista de división en Xamarin.Next let’s examine how the expanding and collapsing behavior of the Split View Controller was implemented in Xamarin. En el AppDelegate, cuando se crea el controlador de vista en dos paneles, se asigna su delegado para controlar estos cambios:In the AppDelegate, when the Split View Controller is created, its delegate is assigned to handle these changes:

public class SplitViewControllerDelegate : UISplitViewControllerDelegate
{
    public override bool CollapseSecondViewController (UISplitViewController splitViewController,
        UIViewController secondaryViewController, UIViewController primaryViewController)
    {
        AAPLPhoto photo = ((CustomViewController)secondaryViewController).Aapl_containedPhoto (null);
        if (photo == null) {
            return true;
        }

        if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
            var viewControllers = new List<UIViewController> ();
            foreach (var controller in ((UINavigationController)primaryViewController).ViewControllers) {
                var type = controller.GetType ();
                MethodInfo method = type.GetMethod ("Aapl_containsPhoto");

                if ((bool)method.Invoke (controller, new object[] { null })) {
                    viewControllers.Add (controller);
                }
            }

            ((UINavigationController)primaryViewController).ViewControllers = viewControllers.ToArray<UIViewController> ();
        }

        return false;
    }

    public override UIViewController SeparateSecondaryViewController (UISplitViewController splitViewController,
        UIViewController primaryViewController)
    {
        if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
            foreach (var controller in ((CustomNavigationController)primaryViewController).ViewControllers) {
                var type = controller.GetType ();
                MethodInfo method = type.GetMethod ("Aapl_containedPhoto");

                if (method.Invoke (controller, new object[] { null }) != null) {
                    return null;
                }
            }
        }

        return new AAPLEmptyViewController ();
    }
}

El método SeparateSecondaryViewController prueba para ver si se está mostrando una foto y toma medidas en función de ese estado.The SeparateSecondaryViewController method tests to see if a photo is being displayed and takes action based on that state. Si no se muestra ninguna foto, se contrae el controlador de vista secundario para que se muestre el controlador de vista principal.If no photo is being shown it collapses the Secondary View Controller so that the Master View Controller is displayed.

El método CollapseSecondViewController se usa al expandir el controlador de vista en dos paneles para ver si hay fotografías en la pila, en caso de que se contraiga de nuevo a esa vista.The CollapseSecondViewController method is used when expanding the Split View Controller to see if any photos exist on the stack, if so it collapses back to that view.

Moverse entre controladores de vistaMoving Between View Controllers

A continuación, echemos un vistazo a cómo se mueve la aplicación Adaptive photos entre los controladores de vista.Next, let’s take a look at how the Adaptive Photos application moves between view controllers. En la clase AAPLConversationViewController cuando el usuario selecciona una celda de la tabla, se llama al método ShowDetailViewController para mostrar la vista de detalles:In the AAPLConversationViewController class when the user selects a cell from the table, the ShowDetailViewController method is called to display the details view:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    var photo = PhotoForIndexPath (indexPath);
    var controller = new AAPLPhotoViewController ();
    controller.Photo = photo;

    int photoNumber = indexPath.Row + 1;
    int photoCount = (int)Conversation.Photos.Count;
    controller.Title = string.Format ("{0} of {1}", photoNumber, photoCount);
    ShowDetailViewController (controller, this);
}

Mostrar indicadores de divulgaciónDisplaying Disclosure Indicators

En la aplicación fotográfico adaptable hay varios lugares en los que los indicadores de divulgación se ocultan o se muestran en función de los cambios en el entorno de rasgo.In the Adaptive Photo application there are several places where Disclosure Indicators are hidden or shown based on changes to the Trait Environment. Esto se controla con el código siguiente:This is handled with the following code:

public bool Aapl_willShowingViewControllerPushWithSender ()
{
    var selector = new Selector ("Aapl_willShowingViewControllerPushWithSender");
    var target = this.GetTargetViewControllerForAction (selector, this);

    if (target != null) {
        var type = target.GetType ();
        MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
        return (bool)method.Invoke (target, new object[] { });
    } else {
        return false;
    }
}

public bool Aapl_willShowingDetailViewControllerPushWithSender ()
{
    var selector = new Selector ("Aapl_willShowingDetailViewControllerPushWithSender");
    var target = this.GetTargetViewControllerForAction (selector, this);

    if (target != null) {
        var type = target.GetType ();
        MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
        return (bool)method.Invoke (target, new object[] { });
    } else {
        return false;
    }
}

Estos se implementan mediante el método GetTargetViewControllerForAction descrito en detalle anteriormente.These are implemented using the GetTargetViewControllerForAction method discussed in detail above.

Cuando un controlador de vista de tabla muestra datos, usa los métodos implementados anteriormente para ver si se va a producir o no una inserciones y si se muestra o no el indicador de divulgación en consecuencia:When a Table View Controller is displaying data, it uses the methods implemented above to see whether or not a push is going to happen, and whether or not to display or hide the Disclosure Indicator accordingly:

public override void WillDisplay (UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
    bool pushes = ShouldShowConversationViewForIndexPath (indexPath) ?
         Aapl_willShowingViewControllerPushWithSender () :
         Aapl_willShowingDetailViewControllerPushWithSender ();

    cell.Accessory = pushes ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
    var conversation = ConversationForIndexPath (indexPath);
    cell.TextLabel.Text = conversation.Name;
}

Nuevo tipo de ShowDetailTargetDidChangeNotificationNew ShowDetailTargetDidChangeNotification Type

Apple ha agregado un nuevo tipo de notificación para trabajar con clases de tamaño y entornos de rasgos desde un controlador de vista en dos paneles, ShowDetailTargetDidChangeNotification.Apple has added a new notification type for working with Size Classes and Trait Environments from within a Split View Controller, ShowDetailTargetDidChangeNotification. Esta notificación se envía cuando cambia la vista de detalles de destino de un controlador de vista en dos paneles, por ejemplo, cuando el controlador se expande o se contrae.This notification gets sent whenever the target Detail View for a Split View Controller changes, such as when the controller expands or collapses.

La aplicación Adaptive photos usa esta notificación para actualizar el estado del indicador de divulgación cuando cambia el controlador de vista de detalle:The Adaptive Photos application uses this notification to update the state of the Disclosure Indicator when the Detail View Controller changes:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    TableView.RegisterClassForCellReuse (typeof(UITableViewCell), AAPLListTableViewControllerCellIdentifier);
    NSNotificationCenter.DefaultCenter.AddObserver (this, new Selector ("showDetailTargetDidChange:"),
        UIViewController.ShowDetailTargetDidChangeNotification, null);
    ClearsSelectionOnViewWillAppear = false;
}

Eche un vistazo más de cerca a la aplicación Adaptive photos para ver todas las formas en que las clases de tamaño, las colecciones de rasgos y los controladores de vistas adaptables se pueden usar para crear fácilmente una aplicación unificada en Xamarin. iOS.Take a closer look at the Adaptive Photos application to see all of the ways that Size Classes, Trait Collections and Adaptive View Controllers can be used to easily create a Unified Application in Xamarin.iOS.

Guiones gráficos unificadosUnified Storyboards

Como novedad de iOS 8, los guiones gráficos unificados permiten al desarrollador crear un archivo de guion gráfico unificado que se puede mostrar en dispositivos iPhone y iPad mediante el destino de varias clases de tamaño.New to iOS 8, Unified Storyboards allow the developer to create one, unified storyboard file that can be displayed on both iPhone and iPad devices by targeting multiple Size Classes. Mediante el uso de guiones gráficos unificados, el desarrollador escribe menos código específico de la interfaz de usuario y solo tiene un diseño de interfaz para crear y mantener.By using Unified Storyboards, the developer writes less UI specific code and has only one interface design to create and maintain.

Las ventajas principales de los guiones gráficos unificados son:The key benefits of Unified Storyboards are:

  • Use el mismo archivo de guion gráfico para iPhone y iPad.Use the same storyboard file for iPhone and iPad.
  • Implementación inversa en iOS 6 e iOS 7.Deploy backwards to iOS 6 and iOS 7.
  • Obtenga una vista previa del diseño de los distintos dispositivos, orientaciones y versiones del sistema operativo desde el diseñador de Xamarin iOS.Preview the layout for different devices, orientations and OS versions all from within the Xamarin iOS Designer.

Esta característica es totalmente compatible con Visual Studio para MacThis feature is fully supported in Visual Studio for Mac

Habilitar clases de tamañoEnabling Size Classes

De forma predeterminada, cualquier nuevo proyecto de Xamarin. iOS nos dará tamaño a las clases.By default, any new Xamarin.iOS project will us size classes. Para usar clases de tamaño y objetos segue adaptables dentro de un guion gráfico de un proyecto anterior, primero se debe convertir al formato de guion gráfico unificado Xcode 6 desde dentro del diseñador de iOS.To use Size Classes and Adaptive Segues inside a storyboard from an older project, it must first be converted to the Xcode 6 Unified Storyboard format from inside the iOS Designer.

Para ello, abra el guion gráfico que se va a convertir en el diseñador de iOS y active la casilla usar clases de tamaño :To do this open the Storyboard to be converted in the iOS Designer and check the Use Size Classes check box:

IOS Designer confirmará que el desarrollador desea convertir el formato del guion gráfico para usar las clases de tamaño:The iOS Designer will confirm that the developer wants to convert the format of the storyboard to use Size Classes:

Importante

También debe comprobarse el diseño automático para que las clases de tamaño funcionen correctamente.Auto Layout must also be checked for Size Classes to work correctly.

Tipos de dispositivos genéricosGeneric Device Types

Una vez que el guion gráfico se ha convertido para usar clases de tamaño, se volverá a mostrar en el Superficie de diseño y la vista como dispositivo será genérica:Once the storyboard has been converted to use Size Classes, it will be redisplayed in the Design Surface and the View As device will be Generic:

Cuando se selecciona el tipo de dispositivo genérico, se cambia el tamaño de todos los controladores de vista a un cuadrado de 600 x 600.When the Generic device type is selected, all View Controllers will be resized to a 600 x 600 Square. Este cuadrado representa los tamaños de cualquier ancho y cualquier alto.This square represents sizes of any width and any height. Cuando el diseñador de iOS está en este modo, cualquier edición se aplicará a todas las clases de tamaño.When the iOS Designer is in this mode, any edits will apply to all of the Size Classes.

El desarrollador también tiene la opción de ver la superficie de diseño como un iPhone:The developer also has the option of viewing the design surface as an iPhone:

O verlo como iPad:Or viewing it as an iPad:

Seleccionar una clase de tamañoSelect a Size Class

El botón selector de clase de tamaño está en la esquina superior izquierda del Superficie de diseño (cerca de la vista como lista desplegable).The Size Class Selector button is at the upper left hand corner of the Design Surface (near the View As dropdown). Permite al desarrollador seleccionar las clases de tamaño que se están editando actualmente:It allows the developer to select which Size Classes are currently being edited:

El selector presenta la selección de clase de tamaño como una cuadrícula de 3 x 3.The selector presents the Size Class selection as a 3 x 3 grid. Cada uno de los cuadrados de la cuadrícula representa una combinación de una clase width y una clase height.Each of the squares in the grid represents a combination of a Width Class and a Height Class. El cuadrado central selecciona la clase cualquier ancho/cualquier tamaño de alto (que es la vista predeterminada de un guión gráfico unificado).The center square selects the Any Width/Any Height Size class (which is the default view for a Unified Storyboard). Cuando se selecciona este cuadrado, el desarrollador está editando el diseño predeterminado, que es heredado por todas las demás configuraciones.When this square is selected, the developer is editing the default layout, which is inherited by all the other configurations.

El cuadrado situado en la esquina superior izquierda de la cuadrícula representa la clase de tamaño compacto/ancho compacto:The square in the upper left hand corner of the grid represents the Compact Width/Compact Height Size Class:

Este modo corresponde a un iPhone en la orientación horizontal.This mode corresponds to an iPhone in the landscape orientation. El cuadrado situado en la esquina inferior derecha de la cuadrícula representa la clase de tamaño normal de ancho y alto normal, que representa un iPad:The square in the lower right hand corner of the grid represents the Regular Width/Regular Height Size Class, which represents an iPad:

Para editar el diseño de un iPhone en orientación vertical, seleccione el cuadrado en la esquina inferior izquierda.To edit the layout for an iPhone in the portrait orientation, select the square in the lower left hand corner. Representa la clase de tamaño de ancho compacto/alto normal:This represents the Compact Width/Regular Height Size Class:

Haga clic en el cuadrado para seleccionarlo y el Superficie de diseño cambiará el tamaño de los controladores de vista para que coincidan con la nueva selección:Click in the square to select it and the Design Surface will change the size of the View Controllers to match the new selection:

Vea la sección sobre la clase de tamaño de este artículo para obtener más información sobre las clases de tamaño y cómo afectan al diseño de iPhone y iPad.See the Size Class section of this article for more information on Size Classes and how they affect layout for iPhones and iPads.

Tipos de segue adaptablesAdaptive Segue Types

Si el desarrollador ha usado guiones gráficos antes, estará familiarizado con los tipos de segue existentes de las inserciones, modales y elemento flotante.If the developer has used storyboards before, then they will be familiar with the existing segue types of Push, Modal and Popover. Cuando las clases de tamaño están habilitadas en un archivo de guion gráfico unificado, los siguientes tipos de segue adaptables (que corresponden a la nueva API del controlador de vista descritos anteriormente) están disponibles: Mostrar y Mostrar detalles.When Size Classes are enabled on a Unified Storyboard file, the following Adaptive Segue Types (that correspond to the new View Controller API discussed above) are made available: Show and Show Detail.

Importante

Cuando se habilitan las clases de tamaño, cualquier objetos segue existente se convertirá en los nuevos tipos.When Size Classes are enabled, any existing segues will be converted to the new types.

Tome el ejemplo de una aplicación de iOS 8 que usa un guion gráfico unificado con un controlador de vista en dos paneles que tiene un menú de navegación de juegos simple en la vista maestra.Take the example of an iOS 8 Application that uses a Unified Storyboard with a Split View Controller that has a simple game navigation menu in the Master View. Si el usuario hace clic en un botón de menú, el controlador de vista del elemento seleccionado debe mostrarse en la sección de detalles del controlador de vista en dos paneles cuando se ejecuta en un iPad.If the user clicks on a menu button, the selected item’s View Controller should be shown in the Details section of the Split View Controller when running on an iPad. En un iPhone, el controlador de vista del elemento se debe insertar en la pila de navegación.On an iPhone the item’s View Controller should be pushed onto the Navigation stack.

Para lograr este efecto, en el control del diseñador de iOS, haga clic en el botón y arrastre una línea hasta el controlador de vista que se va a mostrar.To achieve this effect, in the iOS Designer control-click on the button and drag a line to the View Controller to be displayed. Cuando se suelte el botón del mouse, seleccione Show Detail en el menú emergente tipo de segue:When the mouse button is released, select Show Detail from the Segue Type Popup menu:

Se creará el nuevo segue entre el botón y el controlador de vista.The new segue will be created between the button and the View Controller. Ahora ejecute la aplicación en el simulador de iPhone y se mostrará el menú principal:Now run the application in the iPhone Simulator and the Main Menu will be displayed:

Haga clic en el botón seleccionar juego y el controlador de vista del elemento se insertará en la pila de navegación:Click on the Select Game button and the item’s View Controller will be pushed onto the Navigation Stack:

Detenga el simulador de iPhone y ejecute la aplicación en el simulador de iPad.Stop the iPhone Simulator and run the Application in the iPad Simulator. Cambiar a la orientación horizontal y volver a mostrar el menú principal:Switch to the landscape orientation and the main menu is again displayed:

De nuevo, haga clic en el botón seleccionar juego y el controlador de vista del elemento se muestra en la sección de detalles del controlador de vista en dos paneles:Again, click on the Select Game button and the item’s View Controller is shown in the Details section of the Split View Controller:

Exclusión de un elemento de una clase de tamañoExcluding an Element from a Size Class

Hay ocasiones en las que un elemento determinado (como una vista, un control o una restricción) no es necesario dentro de una clase de tamaño específica.There are times when a given element (such as a View, Control or a Constraint) is not required inside of a specific Size Class. Para excluir un elemento de una clase de tamaño, seleccione el elemento que desee excluir en el superficie de diseño.To exclude an element from a Size Class, select the desired item to exclude in the Design Surface. Desplácese hasta la parte inferior del Explorador de propiedades y haga clic en el menú desplegable engranaje .Scroll to the bottom of the Property Explorer and click the Gear Dropdown menu. Seleccione la combinación de ancho y alto del que se va a excluir el elemento:Select the combination of Width and Height to exclude the item from:

Se agregará un nuevo caso de exclusión al elemento en la parte inferior del Explorador de propiedades.A new Exclusion Case will be added to the element in the bottom of the Property Explorer. A continuación, desactive la casilla instalado de la clase de tamaño dado:Next, uncheck the Installed checkbox for the given Size Class:

Cambie el Superficie de diseño al ancho y el alto del que se excluyó el elemento, ya que se ha quitado de la clase de tamaño especificada, pero no del diseño de la interfaz de usuario completo:Switch the Design Surface to the Width and Height that the item was excluded from, it has been removed from the given Size Class, but not the entire UI design:

Volver a la clase any width/any height size y el elemento sigue en su lugar:Switching back to the Any Width/Any Height size class and the element is still in place:

Cuando la aplicación se ejecuta en el simulador de iPad, aparece el elemento:When the application is run in the iPad Simulator, the element appears:

Y cuando la aplicación se ejecuta en el simulador de iPhone, falta el elemento:And when the application is run on the iPhone Simulator, the element is missing:

Para quitar un caso de exclusión de un elemento, basta con seleccionar el elemento en el superficie de diseño, desplazarse hasta la parte inferior del Explorador de propiedades y hacer clic en el botón - situado junto al caso que se va a quitar.To remove an Exclusion Case from an element, simply select the element in the Design Surface, scroll to the bottom of the Property Explorer and click the - button beside the case to remove.

Para ver una implementación de guiones gráficos unificados, consulte la aplicación de ejemplo UnifiedStoryboard Xamarin iOS 8 asociada a este documento.To see an implementation of Unified Storyboards, look at the UnifiedStoryboard sample Xamarin iOS 8 application attached to this document.

Pantallas de inicio dinámicoDynamic Launch Screens

El archivo de pantalla de inicio se muestra como una pantalla de presentación mientras se inicia una aplicación de iOS para proporcionar comentarios al usuario de que la aplicación se está iniciando realmente.The launch screen file is displayed as a splash screen while an iOS application is launching to provide feedback to the user that the app is actually starting-up. Antes de iOS 8, el desarrollador tendría que incluir varios Default.png recursos de imagen para cada tipo de dispositivo, orientación y resolución de pantalla en la que se ejecutaba la aplicación.Prior to iOS 8, the developer would have to include multiple Default.png image assets for each device type, orientation and screen resolution that the application would be running on. Por ejemplo, Default@2x.png, Default-Landscape@2x~ipad.png, Default-Portrait@2x~ipad.png, etc.For example, Default@2x.png, Default-Landscape@2x~ipad.png, Default-Portrait@2x~ipad.png, etc.

La factorización en los nuevos dispositivos iPhone 6 y iPhone 6 más (y el próximo Apple Watch) con todos los dispositivos iPhone y iPad existentes, representa una gran variedad de tamaños variables, orientaciones y resoluciones de Default.png recursos de imagen de la pantalla de inicio que se deben crear y mantener.Factoring in the new iPhone 6 and iPhone 6 Plus devices (and the upcoming Apple Watch) with all the existing iPhone and iPad devices, this represents a large array of varying sizes, orientations and resolutions of Default.png startup screen image assets that must be created and maintained. Además, estos archivos pueden ser bastante grandes y se "inflarán" el paquete de aplicaciones de entrega, lo que aumenta la cantidad de tiempo necesario para descargar la aplicación desde iTunes App Store (posiblemente para que se pueda entregar a través de una red de telefonía móvil) y el aumento de la cantidad de almacenamiento necesario en el dispositivo del usuario final.In addition, these files can be quite large and will "bloat" the deliverable application bundle, increasing the amount of time required to download the application from the iTunes App Store (possibly keeping it from being able to be delivered over a cellular network) and increasing the amount of storage required on the end user's device.

Como novedad de iOS 8, el desarrollador puede crear un único archivo de .xib atómico en Xcode que use las clases de diseño y tamaño automáticos para crear una pantalla de inicio dinámico que funcione en todos los dispositivos, resoluciones y orientaciones.New to iOS 8, the developer can create a single, atomic .xib file in Xcode that uses Auto Layout and Size Classes to create a Dynamic Launch Screen that will work for every device, resolution and orientation. Esto no solo reduce la cantidad de trabajo necesario para que el desarrollador cree y mantenga todos los recursos de imagen necesarios, pero reduce en gran medida el tamaño del paquete instalado de la aplicación.This not only reduces the amount of work required of the developer to create and maintain all the required image assets, but it greatly reduces the size of the application's installed bundle.

Las pantallas de inicio dinámico tienen las siguientes limitaciones y consideraciones:Dynamic Launch Screens have the following limitations and considerations:

  • Use solo UIKit clases.Use only UIKit classes.
  • Use una vista raíz única que sea un objeto UIView o UIViewController.Use a single root view that is a UIView or UIViewController object.
  • No realice ninguna conexión con el código de la aplicación (no agregue acciones ni salidas).Don’t make any connections to the application's code (don’t add Actions or Outlets).
  • No agregue UIWebView objetos.Don’t add UIWebView objects.
  • No utilice ninguna clase personalizada.Don’t use any custom classes.
  • No utilice atributos en tiempo de ejecución.Don’t use runtime attributes.

Teniendo en cuenta las instrucciones anteriores, echemos un vistazo a la adición de una pantalla de inicio dinámico a un proyecto existente de Xamarin iOS 8.With the above guidelines in mind, let's look at adding a Dynamic Launch Screen to an existing Xamarin iOS 8 project.

Haga lo siguiente:Do the following:

  1. Abra Visual Studio para Mac y cargue la solución para agregar la pantalla de inicio dinámico a.Open Visual Studio for Mac and load the Solution to add the Dynamic Launch Screen to.

  2. En el Explorador de soluciones, haga clic con el botón derecho en el archivo MainStoryboard.storyboard y seleccione abrir con > Xcode Interface Builder:In the Solution Explorer, right-click the MainStoryboard.storyboard file and select Open With > Xcode Interface Builder:

  3. En Xcode, seleccione archivo > nuevo archivo de > ... :In Xcode, select File > New > File...:

  4. Seleccione interfaz de usuario de iOS > > pantalla de inicio y haga clic en el botón siguiente :Select iOS > User Interface > Launch Screen and click the Next button:

  5. Asigne un nombre al archivo LaunchScreen.xib y haga clic en el botón crear :Name the file LaunchScreen.xib and click the Create button:

  6. Edite el diseño de la pantalla de inicio mediante la adición de elementos gráficos y el uso de restricciones de diseño para colocarlos en los dispositivos, las orientaciones y los tamaños de pantalla especificados:Edit the design of the launch screen by adding graphic elements and using Layout Constraints to position them for the given devices, orientations and screen sizes:

  7. Guarde los cambios en LaunchScreen.xib.Save the changes to LaunchScreen.xib.

  8. Seleccione el destino de las aplicaciones y la pestaña General :Select the Applications Target and the General tab:

  9. Haga clic en el botón elegir info. plist , seleccione el Info.plist de la aplicación Xamarin y haga clic en el botón elegir :Click the Choose Info.plist button, select the Info.plist for the Xamarin app and click the Choose button:

  10. En la sección iconos de la aplicación e imágenes de inicio , abra el menú desplegable de archivo de pantalla de inicio y elija el LaunchScreen.xib creado anteriormente:In the App Icons and Launch Images section, open the Launch Screen File dropdown and choose the LaunchScreen.xib created above:

  11. Guarde los cambios en el archivo y vuelva a Visual Studio para Mac.Save the changes to the file and return to Visual Studio for Mac.

  12. Espere a que Visual Studio para Mac termine de sincronizar los cambios con Xcode.Wait for Visual Studio for Mac to finish syncing changes with Xcode.

  13. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta de recursos y seleccione Agregar > Agregar archivos... :In the Solution Explorer, right-click on the Resource folder and select Add > Add Files...:

  14. Seleccione el archivo de LaunchScreen.xib creado anteriormente y haga clic en el botón abrir :Select the LaunchScreen.xib file created above and click the Open button:

  15. Compile la aplicación.Build the application.

Prueba de la pantalla de inicio dinámicoTesting the Dynamic Launch Screen

En Visual Studio para Mac, seleccione el simulador de retina de iPhone 4 y ejecute la aplicación.In Visual Studio for Mac, select the iPhone 4 Retina simulator and run the application. La pantalla de inicio dinámico se mostrará en el formato y la orientación correctos:The Dynamic Launch Screen will be displayed in the correct format and orientation:

Detenga la aplicación en Visual Studio para Mac y seleccione un dispositivo iPad iOS 8.Stop the application in Visual Studio for Mac and select an iPad iOS 8 device. Ejecute la aplicación y la pantalla de inicio tendrá el formato correcto para el dispositivo y la orientación:Run the application and the launch screen will be correctly formatted for this device and orientation:

Vuelva a Visual Studio para Mac y detenga la ejecución de la aplicación.Return to Visual Studio for Mac and stop the application from running.

Trabajar con iOS 7Working with iOS 7

Para mantener la compatibilidad con versiones anteriores de iOS 7, solo tiene que incluir los recursos de imagen Default.png habituales de la forma habitual en la aplicación iOS 8.To maintain backward compatibility with iOS 7, just include the usual Default.png image assets as normal in the iOS 8 application. iOS volverá al comportamiento anterior y usará esos archivos como pantalla de inicio cuando se ejecute en un dispositivo iOS 7.iOS will return to the previous behavior and use those files as the startup screen when running on an iOS 7 device.

Para ver una implementación de una pantalla de inicio dinámico en Xamarin, consulte la aplicación de ejemplo de pantallas de inicio dinámicos de iOS 8 adjuntada a este documento.To see an implementation of a Dynamic Launch Screen in Xamarin, look at the Dynamic Launch Screens sample iOS 8 application attached to this document.

ResumenSummary

En este artículo se ha examinado rápidamente las clases de tamaño y cómo afectan al diseño en dispositivos iPhone y iPad.This article took a quick look at Size Classes and how they affect layout in iPhone and iPad devices. Se ha explicado cómo funcionan los rasgos, los entornos de rasgos y las colecciones de rasgos con clases de tamaño para crear interfaces unificadas.It discussed how Traits, Trait Environments and Trait Collections work with Size Classes to create Unified Interfaces. Ha tenido un breve vistazo a los controladores de vistas adaptables y cómo funcionan con clases de tamaño dentro de interfaces unificadas.It took brief look at Adaptive View Controllers and how they work with Size Classes inside of Unified Interfaces. En ella, se examinó la implementación de clases de tamaño C# y de interfaces unificadas por completo desde el código dentro de una aplicación Xamarin iOS 8.It looked at implementing Size Classes and Unified Interfaces completely from C# code inside a Xamarin iOS 8 application.

Por último, en este artículo se han tratado los conceptos básicos de la creación de guiones gráficos unificados con Xamarin iOS Designer que funcionará en dispositivos iOS y creará una única pantalla de inicio dinámico que se mostrará como pantalla de inicio en cada dispositivo iOS 8.Finally, this article covered the basics of creating Unified Storyboards with the Xamarin iOS Designer that will work across iOS devices and creating a single, Dynamic Launch Screen that will be displayed as the startup screen on every iOS 8 device.