DEV Community

Felipe Carvalho
Felipe Carvalho

Posted on

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

Top comments (0)