Uma Simples Tela Criada Usando UIKit/ViewCode e Flutter

felcarv01

Felipe Carvalho

Posted on November 18, 2024

Uma Simples Tela Criada Usando UIKit/ViewCode e Flutter

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
}
Enter fullscreen mode Exit fullscreen mode

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()
    }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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")
    }
}
Enter fullscreen mode Exit fullscreen mode

Assim, criamos a seguinte tela:

Iphone simulator screenshot

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'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

E foram geradas as seguintes telas:

Build Flutter no Android Build Flutter no iPhone
Android emulator screenshot iPhone simulator screenshot

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á!

💖 💪 🙅 🚩
felcarv01
Felipe Carvalho

Posted on November 18, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related