Muy buenas, me llamo Luis y esta vez les traigo un nuevo post.
En este tutorial de iOS 100% programáticamente, comenzaré a hablar sobre mis puntos de vista sobre por qué debería dejar de usar Storyboard y considerar la creación de su diseño de interfaz de usuario para su aplicación iOS 100% programáticamente.
Después de eso, le mostraré cómo construir una interfaz de usuario de pantalla de inicio de sesión simple 100% programáticamente en 4 pasos.
Usé Storyboard para uno de mis proyectos recientes de iOS porque no tenía mucha experiencia en la creación de aplicaciones complejas de iOS.
Pensé que era lo correcto para una aplicación. Sin embargo, encontré algunos problemas al trabajar con Storyboard.
Índice
Problemas encontrados al trabajar con Storyboard
Cuando refactoricé el código cambiando el nombre de la variable IBOutlet / IBAction
después de unos días de trabajo, la aplicación se bloqueó sin razón aparente y tuve que volver a conectarla cada vez que sucedía.
Cuando agregué algunas subvistas anidadas debajo de una vista, fue difícil ajustar cuando quería colocar dos subvistas una detrás de la otra. Además de eso, agregarles restricciones fue una de las cosas más frustrantes por hacer.
Tuve la oportunidad de crear una aplicación con alrededor de 35 escenas de Storyboard. Después de cambiar al código completo, noté que el tiempo de compilación fue muy rápido.
Antes tenía un problema que, a medida que agrego más escenas a mi guión gráfico, tenía que esperar un poco más a pesar de que tengo una máquina bastante rápida con una tarjeta gráfica de 2 GB y una memoria de 16 GB.
- No puedo insistir en cuánto más confiable era ese código cuando escribí todo en código sin usar Storyboard.
- Me gusta usar Storyboard para maquetas y prototipos rápidos, pero no para la producción.
- Descubrí que tomó más tiempo que usar Storyboard en algunos casos, como agregar cosas a la vista, etc.
- Sin embargo, en general, creo que ahorré mucho tiempo sin usar Storyboard.
- Quiero decirle a cualquier desarrollador del nuevo iOS que deje de usar Storyboard y diseñe la interfaz de usuario mediante programación en su aplicación de iOS.
- Con el tiempo, de todos modos creará UI Design mediante programación, así que ¿por qué no hacerlo ahora?
- Espero haberte convencido de empezar directamente a crear la interfaz de usuario mediante programación.
Paso # 1: Deshágase del Storyboard y sus referencias.
Paso # 2: Configurar un controlador de vista raíz.
Paso # 3: Agregar subvistas.
Paso # 4: Habilite las restricciones de diseño automático.
- Anímate y crea un proyecto en Xcode.
- Luego, ve al Navegador de proyectos → Guión gráfico principal archivo.
- Golpear Eliminar clave y elija Eliminar referencia para deshacerse de él … Sí, lo escuchaste bien 🙂
- Ir Proyecto Navigator → Carpeta del proyecto de nivel superior → General Pestaña → Información de implementación sección → Borrar el texto Principal desde el campo de entrada, que está junto al Interfaz principal etiqueta, como en la imagen de abajo.
- Ir a Proyecto Navigator →
Info.plist archivo
→ Manifiesto de la escena de la aplicación property → Scene Configuration → Item 0 y deshacerse de la propiedad Storyboard Name haciendo clic en el icono que tiene un signo menos en el círculo al lado.
► Ejecute la aplicación y verá la pantalla negra y cambiemos eso agregando un controlador de vista raíz.
Abra el archivo SceneDelegate.swift
desde el Navegador de proyectos y agregue el siguiente código al método willConnectTo ()
:
Reemplazar el código existente por:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) guard let winScene = (scene as? UIWindowScene) else return window = UIWindow(windowScene: winScene) window?.rootViewController = ViewController() window?.makeKeyAndVisible()
Asegúrese de que ViewController ()
que está asignado al rootViewController
de la ventana coincida con el nombre de archivo ViewController.Swift
.
Una cosa más que quiero hacer antes de ejecutar la aplicación es agregar un color de fondo a la clase ViewController ()
para poder asegurarme de que funciona correctamente.
Ir ViewController.swift
archivo de clase → método viewDidLoad ()
.
Agregue el siguiente código a ese método.
view.backgroundColor = .systemRed
Si todo va bien, debería poder ver el color de fondo similar al de la captura de pantalla anterior cuando ejecuta la aplicación.
Voy a necesitar cuatro vistas en mi ViewController.swift
para que coincida con el diseño de muestra original.
UIView
.TextFields
.Botón UIB
.
A tener en cuenta: Podría usar UIStackView
para organizar las vistas, sin embargo, en aras de la simplicidad, estoy usando UIView
.
Lo primero que debe hacer es crear UIView
, que es el contenedor para el formulario de inicio de sesión.
- Cree una propiedad llamada
loginContentView
en la claseViewController.swift
, (normalmente por encima del métodoViewDidLoad ()
).
private let loginContentView:UIView = let view = UIView() view.backgroundColor = .gray return view ()
- Asigne una función anónima que se llamará inmediatamente con
()
paréntesis al final, que devolverá el objeto de vista que he inicializado dentro de la función. - Agregue la propiedad
backgroundColor
al objeto de vista y establezca su valor en gris.
Cree las otras tres vistas como propiedades de la clase ViewController
similar a loginContentView
.
Nombre de usuario:
private let unameTxtField:UITextField = let txtField = UITextField() txtField.backgroundColor = .white txtField.placeholder = "Username" txtField.borderStyle = .roundedRect txtField.font = UIFont.preferredFont(forTextStyle: .title2) return txtField ()
Contraseña:
private let pwordTxtField:UITextField = let txtField = UITextField() txtField.placeholder = "Username" txtField.borderStyle = .roundedRect txtField.font = UIFont.preferredFont(forTextStyle: .title2) return txtField ()
Botón de inicio de sesión:
let btnLogin:UIButton = let btn = UIButton(type:.system) btn.backgroundColor = .blue btn.setTitle("Login", for: .normal) btn.tintColor = .white btn.layer.cornerRadius = 5 btn.clipsToBounds = true btn.translatesAutoresizingMaskIntoConstraints = false btn.titleLabel?.font = UIFont.preferredFont(forTextStyle: .title2) btn.contentEdgeInsets = UIEdgeInsets(top: 15,left: 10,bottom: 15,right: 10) return btn ()
Una vez creadas todas las vistas, es hora de añadir ellos a la vista principal.
Vaya al método ViewController.swift
→ ViewDidLoad ()
.
Agregue unameTxtField
, pwordTxtField
y btnLogin
como subvistas de loginContentView
usando el método addSubView ()
, como el código a continuación.
loginContentView.addSubview(unameTxtField) loginContentView.addSubview(pwordTxtField) loginContentView.addSubview(btnLogin)
Luego, agregue loginContentView
como una subvista de la vista principal, así:
view.addSubview(loginContentView)
Ejecútelo y no vea nada … 😕
Para que sean visibles en la pantalla, necesitaremos darles ubicaciones y dimensiones.
Podría usar la propiedad de marco en cada objeto de vista, sin embargo, la mejor manera es usar Restricciones de diseño automático (mediante programación).
Agregue la propiedad translatesAutoresizingMaskIntoConstraints
y establezca su valor en falso para todas las vistas dentro de sus funciones anónimas.
private let loginContentView:UIView = let view = UIView() view.backgroundColor = .gray view.translatesAutoresizingMaskIntoConstraints = false return view ()
Asegúrese de agregar una propiedad translatesAutoresizingMaskIntoConstraints
a las declaraciones de función unameTxtField
, pwordTxtField
y btnLogin
similares a la anterior.
Cree un método llamado setUpAutoLayout ()
que es donde voy a escribir todo el código relacionado con las restricciones.
Dentro de setUpAutoLayout ()
, voy a agregar una restricción de diseño automático a cada vista una por una.
Restricciones de loginContentView
1. Primero, estableceré el margen izquierdo de loginContentView
igual al margen izquierdo de su vista principal y estableceré la propiedad isActive
en true, así.
loginContentView.leadingAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leadingAnchor).isActive = true
2. Haz lo mismo con el ancla adecuada.
loginContentView.trailingAnchor.constraint(equalTo:view.safeAreaLayoutGuide.trailingAnchor).isActive = true
Estas dos restricciones estirarán el ancho de loginContentView
para ajustarse al margen izquierdo y derecho de su vista principal principal.
3. HeightAnchor
: establezca la altura de loginContentView
mediante la restricción hightAnchor
. Solo entonces podrá ver el loginContentView
que aparece en la pantalla.
loginContentView.heightAnchor.constraint(equalToConstant: view.frame.height/3).isActive = true
Como puede ver, configuré la altura de loginContentView
para que coincida con un tercio de la altura de la vista principal de su padre.
Si ejecuta (►) la aplicación en este punto, puede ver que loginContentView
aparece en la parte superior.
Finalmente, necesito mover el loginContentView
al centro de la pantalla verticalmente. Puede lograr esto utilizando otra restricción llamada CenterYAnchor
.
loginContentView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
Ejecútelo y debería poder ver el loginContentView
centrado verticalmente en su vista principal.
Agradable. Pasemos al siguiente.
Restricciones de unameTxtField
1. Voy a agregar la restricción topAnchor a unameTxtField, que determinará dónde debe estar el margen superior de unameTxtField en su vista principal (loginContentView).
Estoy configurando el margen superior de unameTxtField para que coincida con el margen superior de loginContentView con la variable de argumento equalTo.
unameTxtField.topAnchor.constraint(equalTo:loginContentView.topAnchor).isActive = true
Además, puedo usar una constante como una segunda variable de argumento para empujar el unameTxtField un poco hacia abajo desde su vista principal en este caso loginContentView para que tenga algo de espacio entre ellos.
unameTxtField.topAnchor.constraint(equalTo:loginContentView.topAnchor, constant:40).isActive = true
Próximo,
2. Agregue leftAnchor
y rightAnchor
a unameTxtField
.
Ahora, voy a estirar el unameTxtField
para que coincida con sus márgenes principales izquierdo y derecho usando restricciones leftAnchor
y rightAnchor
similares a la anterior.
unameTxtField.leftAnchor.constraint(equalTo:loginContentView.leftAnchor).isActive = true unameTxtField.rightAnchor.constraint(equalTo:loginContentView.rightAnchor).isActive = true
Agreguemos algo de espacio entre ambos lados para que unameTxtField
no toque los márgenes de la pantalla en ninguno de los lados. Para hacer eso, use nuevamente una constante como segundo argumento, como el código siguiente.
unameTxtField.leftAnchor.constraint(equalTo:loginContentView.leftAnchor, constant:20).isActive = true unameTxtField.rightAnchor.constraint(equalTo:loginContentView.rightAnchor, constant:-20).isActive = true
Podría usar las restricciones de la vista principal en lugar de usar las restricciones de loginContentView
.
Hay un problema con el uso de la vista principal. ¿Qué sucede si desea cambiar el ancho de loginContentView
en el futuro? Las subvistas internas
NO se ajustarán correctamente.
Es por eso que utilizo las restricciones de loginContentView
para las vistas de sus hijos.
3. Cambiemos la altura de unameTxtField
usando la restricción heightAnchor
.
unameTxtField.heightAnchor.constraint(equalToConstant:50).isActive = true
Perfecto. Dos vistas más para el final …
PwordTxtField
1. Primero, voy a agregar el ancho del campo de texto usando anclajes de izquierda y derecha similares a unameTxtField
.
pwordTxtField.leftAnchor.constraint(equalTo:loginContentView.leftAnchor, constant:20).isActive = true pwordTxtField.rightAnchor.constraint(equalTo:loginContentView.rightAnchor, constant:-20).isActive = true
2. A continuación, agregue la altura.
pwordTxtField.heightAnchor.constraint(equalToConstant:50).isActive = true
3. Voy a establecer el margen superior de pwordTxtField
en el margen inferior de unameTxtField
usando la restricción bottomAnchor
.
pwordTxtField.topAnchor.constraint(equalTo:unameTxtField.bottomAnchor, constant:20).isActive = true
Restricciones del botón de inicio de sesión
Este es muy similar a pwordTxtField
🙂
btnLogin.topAnchor.constraint(equalTo:pwordTxtField.bottomAnchor, constant:20).isActive = true btnLogin.leftAnchor.constraint(equalTo:loginContentView.leftAnchor, constant:20).isActive = true btnLogin.rightAnchor.constraint(equalTo:loginContentView.rightAnchor, constant:-20).isActive = true btnLogin.heightAnchor.constraint(equalToConstant:50).isActive = true
Si desea saber más sobre cómo agregar restricciones mediante programación, puede consultar la documentación de Apple aquí.
Espero que comprenda por qué dejé de usar el guión gráfico y comencé a crear el diseño de la interfaz de usuario mediante programación.
Además, gracias por acompañarme en la creación de un diseño de pantalla de inicio de sesión PRO gramáticamente.
¿Qué desafíos crees que vas a enfrentar si cambias a construir la interfaz de usuario al 100% mediante programación? Espero leer sus comentarios … 👍
Añadir comentario