Uma Simples Tela Criada Usando UIKit/ViewCode e Flutter
Felipe Carvalho
Posted on November 18, 2024
Criei uma tela bem simples com apenas três elementos dispostos verticalmente: um título, um campo de texto e um botão. Neste post, veremos qual tecnologia é mais simples de implementar. Neste exemplo, não me preocupei em explicar cada parte do código. Caso queiram, posso fazê-lo no futuro.
1️⃣ Usando UIKit e ViewCode:
Antes de iniciar a criação das telas programaticamente tive que remover todas as referências ao arquivo Main.storyboard
e incluir o seguinte código no arquivo SceneDelegate.swift
deixando o método scene
assim:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let taskMasterVC = HomeViewController()
window.rootViewController = UINavigationController(rootViewController: taskMasterVC)
window.makeKeyAndVisible()
self.window = window
}
Agora que está tudo configurado, criei uma interface ViewCode.swift
para melhorar a implementação do ViewCode
.
protocol ViewCode {
func addSubviews()
func setupConstraints()
func setupStyles()
}
extension ViewCode {
func setup() {
addSubviews()
setupConstraints()
setupStyles()
}
}
A View
foi criada no arquivo HomeView.swift
com o seguinte código contendo os elementos.
import UIKit
class HomeView: UIView {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .systemFont(ofSize: 22, weight: .semibold)
return label
}()
private lazy var textInputTask: UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.placeholder = "Enter a task"
textField.borderStyle = .roundedRect
textField.layer.cornerRadius = 8
return textField
}()
private lazy var addTaskBT: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(.white, for: .normal)
button.backgroundColor = .systemBlue
button.layer.cornerRadius = 8
return button
}()
init() {
super.init(frame: .zero)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup(titleText: String, addTaskButtonTitle: String) {
titleLabel.text = titleText
addTaskBT.setTitle(addTaskButtonTitle, for: .normal)
}
}
extension HomeView: ViewCode {
func addSubviews() {
addSubview(titleLabel)
addSubview(textInputTask)
addSubview(addTaskBT)
}
func setupConstraints() {
NSLayoutConstraint.activate(
[
titleLabel.topAnchor
.constraint(
equalTo: safeAreaLayoutGuide.topAnchor, constant: 12),
titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
textInputTask.topAnchor
.constraint(equalTo: titleLabel.bottomAnchor, constant: 18),
textInputTask.leadingAnchor
.constraint(equalTo: leadingAnchor, constant: 16),
textInputTask.trailingAnchor
.constraint(equalTo: trailingAnchor, constant: -16),
addTaskBT.topAnchor
.constraint(
equalTo: textInputTask.bottomAnchor, constant: 12),
addTaskBT.centerXAnchor.constraint(equalTo: centerXAnchor),
addTaskBT.widthAnchor.constraint(equalToConstant: 120),
]
)
}
func setupStyles() {
backgroundColor = .white
}
}
Aqui podemos ver que o uso do protocolo ViewCode
melhora a legibilidade e a organização, mas como podemos ver isso na tela do dispositivo? Agora entra o último arquivo: HomeViewController.swift
.
import UIKit
class HomeViewController: UIViewController {
private lazy var homeView: HomeView = {
return HomeView()
}()
override func loadView() {
super.loadView()
self.view = homeView
}
override func viewDidLoad() {
super.viewDidLoad()
homeView.setup(titleText: "Task Master", addTaskButtonTitle: "Add Task")
}
}
Assim, criamos a seguinte tela:
2️⃣ Usando Flutter:
No Flutter, como podemos criar builds tanto para Android quanto para iOS, usamos o mesmo código para ambos:
Poderíamos separar os componentes em arquivos, o que é uma boa prática. Mas, como neste exemplo não haverá reuso, deixei tudo no arquivo main.dart
.
import 'package:flutter/material.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 12, left: 16, right: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
'Task Master',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 18),
const TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter a task',
),
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
child: const Text('Add Task'),
),
],
),
),
),
);
}
}
E foram geradas as seguintes telas:
Build Flutter no Android | Build Flutter no iPhone |
---|---|
Daria para deixar exatamente iguais? 🤔 Sim, daria, mas não quis me prolongar em relação a estilizar os componentes.
Caso encontre algum erro ou queira contribuir pode deixar nos comentários.
Em um próximo momento, falarei mais detalhadamente sobre cada parte do código.
Até lá!
Posted on November 18, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.