Prática 3: Criando as telas de Configurações

Assista e acompanhe a prática em sala dos exercícios "Criando as telas de Configurações". Execute as instruções conforme a apresentação.

Exercício 1: Criando a Tela de Atividades

1.1. Adicione um Table View Controller ao Storybaord

No arquivo Main.storyboard adicione um novo View Controller do tipo Table View Controller abaixo do de Nova Sessão.

1.2. Crie um relationship segue para o novo View Controller

No arquivo Main.storyboard a partir do Tab Bar Controller crie um relationship segue.

1.3. Configure o ícone do Tab Bar

No arquivo Main.storyboard selecione o ícone da Tab Bar do View Controller criado e no Attribute Inspector modifique as propriedades para:

  • Título: Configurações
  • Image: TabBarIcon_Configurations.

Exercício 2: Listando as Atividades

2.1. Crie a classe ActivitiesTableViewController usando o template Cocoa Touch Class

A classe deve ficar dentro do grupo ViewControllers e deve herdar de UITableViewController.

2.2. Associe a classe ao View Controller no Storyboard

No arquivo Main.storyboard localize o Table View Controller adicionado no exercício anterior e modifique sua classe para ActivitiesTableViewController no Identity Inspector.

2.3. Adicione propriedades ao View Controller

No arquivo ActivitiesTableViewController.swift adicione uma seção de propriedades no início da classe usando o código abaixo:

//
// MARK: - Propriedades

lazy var activities: [Activity] = TraqtDataContext.sharedInstance.activities.getAll()

//
// MARK: - View Lifecycle

2.4. Atualize o código dos métodos do Data Source

No arquivo ActivitiesTableViewController.swift atualize o código dos métodos do Table View data source conforme abaixo:

//
// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.activities.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("ActivityCell", forIndexPath: indexPath)

    // Configure the cell...
    cell.textLabel!.text = self.activities[indexPath.row].name

    return cell
}

2.5. Configure a célula do Table View

No arquivo Main.storyboard localize o Table View Controller de configurações e selecione a célula na seção Prototype Cells. Modifique a propriedade Style para Basic e o Identifier para ActivityCell.

2.6. Torne o View Controller Embbeded em um Navigation Controller

Modifique o título do View Controller para Atividades.

2.7. Execute o teste o App


Exercício 3: Inserindo um Formulário de Atividades

3.1. Acrescente um View Controller para o formulário

No arquivo Main.storyboard acrescente um novo View Controller ao lado do Table View Controller criado no exercício anterior.

3.2. Crie um Show segue a partir da célula do Controller de Configurações para o novo View Controller

Modifique a propriedade Identifier para EditActivity.

3.3. Crie a classe ActivityFormViewController usando o template Cocoa Touch Class

A classe deve ficar dentro do grupo ViewControllers e deve herdar de UIViewController.

3.4. Associe a classe ao View Controller no Storyboard

No arquivo Main.storyboard localize o Table View Controller adicionado no exercício anterior e modifique sua classe para ActivitiesTableViewController no Identity Inspector.


Exercício 4: Desenhando o Formulário de Atividades

4.1. Desenhe os componentes do formulário

No arquivo Main.storyboard localize o View Controller de formulário criado no exercício anterior e inclua os componentes conforme a table abaixo:

Componente X Y Width
Label - Nome 16 80 -
Label - Descrição 16 118 -
Label - Repetições 16 156 -
Label - Tempo 16 194 -
TextField - Nome 117 76 467
TextField - Descrição 117 114 467
TextField - Repetições 117 152 467
TextField - Tempo 117 190 467

4.2. Adicione as Constraints padrões

Use o comando Resolve Auto Layout Issues > Add Missing Constraints para adicionar um conjunto de constraints padrões.

4.3. Modifique a propriedade Keyboard Type

Selecione os text fields dos campos Repetições e Tempo e modifique o atributo Keyboard Type para Number Pad

4.4. Inclua o TextView de histórico

Na parte inferior do formulário inclua um componente UITextView ocupando toda a porção restante da tela. Adicione constraints para que ele fique com um espaçamento de 8 pontos do Text Field de tempo e que fique alinhado com a borda inferior e com as laterais esquerda e direita do formulário.

4.5. Inclua os Outlets dos componentes criados

No arquivo ActivityFormViewController.swift inclua os Outlets para os componentes conforme o código abaixo:

//
// MARK: - Outlets

@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var descriptionTextField: UITextField!
@IBOutlet weak var repetitionsTextField: UITextField!
@IBOutlet weak var timeTextField: UITextField!
@IBOutlet weak var historyTextView: UITextView!

Exercício 5: Incluindo a Funcionalidade do Formulário

5.1. Inclua as propriedades da classe ActivityFormViewController

No arquivo ActivityFormViewController.swift inclua suas propriedades conforme o código abaixo:

//
// MARK: - Properties

var activity: Activity?

5.2. Atualize o método viewDidLoad

No arquivo ActivityFormViewController.swift atualize o método conforme o código abaixo:

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    if let a = self.activity {
        self.title = "Editar Atividade"
        self.nameTextField.text = a.name
        self.descriptionTextField.text = a.details
        self.repetitionsTextField.text = a.repetitions!.stringValue
        self.timeTextField.text = a.timeLimit!.stringValue
        self.historyTextView.hidden = false

        // Mostra as sessões realizadas no TextView
        if let sessions = a.sessions where sessions.count > 0 {
            let dateFormatter = NSDateFormatter()
            dateFormatter.dateStyle = .ShortStyle
            dateFormatter.timeStyle = .ShortStyle

            var sessionHistory = "Sessões desta atividade:"
            for session in sessions {
                let s = session as! Session
                sessionHistory += "\n- Sessão em \(dateFormatter.stringFromDate(s.startTime!)), repetições: \(s.totalRepetitions), tempo: \(NSTimeInterval(s.elapsedTime!).getFormattedInterval(miliseconds: false))"
            }
            self.historyTextView.text = sessionHistory
        } else {
            self.historyTextView.text = "Não há sessões registradas para essa atividade."
        }
    } else {
        self.title = "Nova Atividade"
        self.historyTextView.hidden = true
    }
}

5.3. Atualize o método prepareForSegue:sender: na classe ActivitiesTableViewController

No arquivo ActivitiesTableViewController.swift inclua o código para o método conforme abaixo:

//
// MARK: - Navigation

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "EditActivity" {
        let destVC = segue.destinationViewController as! ActivityFormViewController
        let indexPath = self.tableView.indexPathForCell(sender as! UITableViewCell)
        destVC.activity = self.activities[indexPath!.row]
    }
}

5.4. Adicione um Bar Button Item com o identifier Done no Formulário de Atividade

No arquivo Main.storyboard localize o View Controller do Formulário de Atividade e adicione um novo Bar Button Item no lado direito da Navigation Bar.

5.5. Inclua os métodos de apoio

No arquivo ActivityFormViewController.swift inclua os métodos conforme o código abaixo:

//
// MARK: - Métodos de Apoio

func setActivityData(activity: Activity) {
    activity.name = self.nameTextField.text
    activity.details = self.descriptionTextField.text
    if let s1 = self.repetitionsTextField.text, let r = Int(s1) {
        activity.repetitions = r
    }
    if let s2 = self.timeTextField.text, let t = Float(s2) {
        activity.timeLimit = t
    }
}

//
// MARK: - Action Methods

@IBAction func doneTapped(sender: UIBarButtonItem) {
    // Verifica se uma atividade foi carregada, nesse caso significa que estamos editando uma atividade existente
    if let a = self.activity {
        // Usa o método update do EntityDataSource para atualizar os dados de uma entidade
        // Para isso identifica a entidade através de um id
        TraqtDataContext.sharedInstance.activities.update(a.activityId!) {
            self.setActivityData($0)
        }
    } else {
        // Se não cria uma atividade
        TraqtDataContext.sharedInstance.activities.add() {
            self.setActivityData($0)
        }
    }

    // Volta para a tela anterior após concluir a edição
    self.navigationController?.popViewControllerAnimated(true)
}

O Bar Button Item adicionado no item anterior deve ter seu Action Method associado ao código acima.

5.6. Incluir um Bar Button Item com o identifier Add

No arquivo Main.storyboard localize o View Controller de configurações e adicione um novo Bar Button Item no lado direito da Navigation Bar.

5.7. Crie um Segue Show para o formulário de Atividades a partir do novo botão

5.8. Crie um Outlet para o Picker View na tela de Início

No arquivo NewSessionViewController.swift acrescente um novo Outlet para o Picker View conforme o código abaixo:

//
// MARK: - Outlets

@IBOutlet weak var activitiesPickerView: UIPickerView!

5.9. Inclua o método viewWillAppear: na classe NewSessionViewController

No arquivo NewSessionViewController.swift inclua o método conforme o código abaixo:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    // Mantém o picker view sincronziado com o banco de dados do Core Data sempre que ela é exibida
    self.activities = TraqtDataContext.sharedInstance.activities.getAll()
    self.activitiesPickerView.reloadAllComponents()
}

5.10. Inclua o método viewWillAppear: na classe ActivitiesTableViewController

No arquivo ActivitiesTableViewController.swift inclua o método conforme o código abaixo:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    // Mantém o table view sincronziado com o banco de dados do Core Data sempre que ela é exibida
    self.activities = TraqtDataContext.sharedInstance.activities.getAll()
    self.tableView.reloadData()
}