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:
Build ViewCode no iPhone
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á!