Prática 2: Criando as telas de Sessão
Assista e acompanhe a prática em sala dos exercícios "Criando as telas de Sessão". Execute as instruções conforme a apresentação.
Exercício 1: Criando a Tela de Início
1.1. Crie um Grupo para os ViewControllers
Crie um grupo para armazenar os arquivos referentes a View Controllers com o nome ViewControllers.
1.2. Crie a classe NewSessionViewController usando o template Cocoa Touch Class
A classe deve ficar dentro do grupo ViewControllers e deve herdar de UIViewController.
1.3. Associe a classe ao View Controller no Storyboard
No arquivo Main.storyboard localize o View Controller principal e modifique sua classe para NewSessionViewController no Identity Inspector.
1.4. Execute o App e verifique se é apresentada uma tela em branco
Exercício 2: Desenhando a Tela de Início
2.1. Desenhe um UIPickerView centralizado na tela
2.2. Desenhe um UIButton abaixo do Picker View
Desenhe um UIButton abaixo do Picker View e altere seu título para Iniciar Atividade.
2.3. Execute o App no simulador do iPhone 5 e verifique que o layout é apresentado de maneira incorreta
Exercício 3: Ajustando o Layout do App
3.1. Adicione constraints para centralizar verticalmente o UIPickerView
3.2. Adicione constraints para alinhar o UIPickerView com as bordas esquerda e direita do View Controller (respeitando as margens)
3.3. Teste as constraints aplicadas
4.4. Adicione constraints ao UIButton para que seu Centro X fique alinhado com o Centro X do Picker View, e mantendo o espaçamento vertical padrão
5.5. Teste as constraints aplicadas
Exercício 4: Alimentando o Picker View
4.1. Inclua as propriedades no View Controller de Nova Sessão
No arquivo NewSessionViewController.swift inclua uma nova sessão de propriedades conforme o código abaixo:
//
// MARK: - Propriedades
lazy var activities: [Activity] = TraqtDataContext.sharedInstance.activities.getAll()
lazy var selectedActivity: Activity? = self.activities.first
//
// MARK: - View Lifecycle
4.2. Torne o View Controller aderente aos protocolos do Picker View
No arquivo NewSessionViewController.swift modifique a declaração da classe para incluir os protocolos conforme o código abaixo:
class NewSessionViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
4.3. Inclua o código do delegate e data source do Picker View
No arquivo NewSessionViewController.swift inclua o código abaixo:
//
// MARK: - UIPickerViewDataSource
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.activities.count
}
//
// MARK: - UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.selectedActivity = self.activities[row]
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.activities[row].name
}
4.4. Associe o View Controller como Data Source e Delegate do Picker View
No arquivo Main.storyboad localize o View Controller de início, selecione o Picker View e crie uma associação com o View Controller para torna-lo delegate e dataSource do Picker View.
4.5. Execute e teste as alterações
Exercício 5: Re-criando o View Controller de Sessão
5.1. Crie a classe SessionViewController usando o template Cocoa Touch Class
A classe deve ficar dentro do grupo ViewControllers e deve herdar de UIViewController.
5.2. Adicione um View Controller ao Storyboard
No arquivo Main.Storyboard acrescente um novo View Controller a partir do Object Library, posicionado ao lado do View Controller de início.
5.3. Associe a classe ao View Controller no Storyboard
No arquivo Main.storyboard localize o novo View Controller e modifique sua classe para SessionViewController no Identity Inspector.
5.4. Modifique a cor de fundo do View Controller de Sessão para Black Color
5.5. Adicione a barra de título ao View Controller de Sessão
No arquivo Main.storyboard localize o View Controller de Sessão e arraste um Label para dentro dele. Modifique suas dimensões conforme a tabela abaixo:
Propriedade | Valor |
---|---|
X | 0 |
Y | 0 |
Width | 600 |
Height | 80 |
Adicione as Constraints para que o botão fique alinhando com o topo, as laterais esquerda e direita, e mantenha uma altura fixa de 80 pontos.
Modifique as propriedades do Label conforme a tabela abaixo:
Propriedade | Valor | |
---|---|---|
Color | White | |
Alignment | Center | |
Background | #357EAA | |
Font | Headline | |
Text | Plain - [Atividade] |
6. Adicione o Label do Cronometro
No arquivo Main.Storyboard localize o View Controller de Sessão e arraste um Label alinhado com o centro do View Controller. Adicione Constraints para manter o label centralizado na tela com 40 pontos acima do centro vertical.
Modifique as propriedades do Label conforme a tabela abaixo:
Propriedade | Valor | |
---|---|---|
Font | System Bold 24.0 | |
Text | Plain - 00:00:00 |
5.7. Adicione o Label de Repetições
No arquivo Main.Storyboard localize o View Controller de Sessão e arraste mais um Label abaixo do cronometro. Adicione constraints para manter seu centro X igual do cronometro e manter uma distância vertical de 8 pontos para ele. Modifique o título do Label para 1 de 10.
5.8. Adicione o Botão de Opções
No arquivo Main.Storyboard localize o View Controller de Sessão e arraste um Button alinhando com a parte inferior direita da view. Adicione constarias para alinha-lo a 16 pontos da borda direita e inferior.
Modifique o título do Botão para Opções.
Exercício 6: Criando Outlets para os Componentes da Tela
6.1. Abra o View Controller de Sessão com o Assistant Editor
6.2. Adicione uma seção para os Outlets
No arquivo SessionViewController.swift inclua uma sessão para os Outlets e uma separação os métodos de controle do ciclo de vida da View, conforme o código abaixo:
//
// MARK: - Outlets
//
// MARK: - View Lifecycle
6.3. Crie os Outlet dos componentes
Crie um novo Outlet para a Barra de Título com o nome titleLabel. Crie um novo Outlet para o Label de Cronometro com o nome chronometerLabel. Crie um novo Outlet para o Label de Repetições com o nome repetitionsLabel.
Exercício 7: Incluindo as funcionalidades da tela de Sessão
7.1. Inclua as propriedades necessárias na classe SessionViewController
No arquivo SessionViewController.swift incluas as propriedades necessárias conforme o código abaixo:
//
// MARK: - Properties
var sessionTrack: SessionTrack!
var activity: Activity!
var tapRecognizer: UITapGestureRecognizer!
7.2. Acrescente os métodos auxiliares
No final arquivo SessionViewController.swift incluas os métodos conforme o código abaixo:
//
// MARK: - Métodos auxiliares
func configureGestureRecognizers() {
// Configura o gesto de Taps para receber contabilizar as repetições com os toques na tela
self.tapRecognizer = UITapGestureRecognizer(target: self, action: "tapGestureDetected:")
self.tapRecognizer.numberOfTapsRequired = 1
self.view.addGestureRecognizer(self.tapRecognizer)
}
func updateUI() {
self.repetitionsLabel.text = "\(self.sessionTrack.currentRepetitions) de \(self.activity.repetitions!)"
}
/// Esse método é chamado quando o usuário realiza o gesto de toque (tap)
func tapGestureDetected(sender: UITapGestureRecognizer) {
sessionTrack.addRepetition()
updateUI()
}
3. Atualize o método viewDidLoad
No arquivo SessionViewController.swift localize o método viewDidLoad e inclua o código abaixo:
// Configura os Gesture Recognizers
self.configureGestureRecognizers()
// Configura a sessão
self.sessionTrack = SessionTrack(sessionParameters: self.activity)
self.sessionTrack.updateTimerBlock = {
if $1 != nil {
self.chronometerLabel.text = "\($1!.getFormattedInterval(miliseconds: false))"
} else {
self.chronometerLabel.text = "\($0.getFormattedInterval(miliseconds: false))"
}
}
self.sessionTrack.completionBlock = {
// Alerta o usuário da conclusão
let alertC = UIAlertController(title: "Traqt", message: "Sessão concluida.", preferredStyle: .Alert)
alertC.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (alert: UIAlertAction!) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
})
self.presentViewController(alertC, animated: true, completion: nil)
}
self.sessionTrack.startSession()
// Configura a apresentação
self.titleLabel.text = self.activity.name
self.updateUI()
Exercício 8: Mostrando as Opções
8.1. Crie uma seção de Action Methods na classe SessionViewController
No arquivo SessionViewController.swift inclua uma seção para Action Methods no final, conforme o código abaixo:
//
// MARK: - Action Methods
8.2. Crie um Action Method para o botão de opções
Crie um novo Action Method a partir do botão de opções com o nome optionsTapped. Atualize o código do método conforme abaixo:
@IBAction func optionsTapped(sender: UIButton) {
presentActions()
}
8.3. Inclua o método presentActions
No arquivo SessionViewController.swift inclu o método presentActions na seção de métodos auxiliares conforme o código abaixo:
func presentActions() {
// Cria um UIAlertController do tipo Commands Sheet para apresentar as opções
let commandsSheet = UIAlertController(title: "Atividade em Andamento", message: "Comandos disponíveis para a sessão.", preferredStyle: .ActionSheet)
// Comandos de pause/retomada
if self.sessionTrack.sessionState == .Running {
let actionPause = UIAlertAction(title: "Pausar", style: .Default) { [weak session = self.sessionTrack] (alert) in session!.pauseSession() }
commandsSheet.addAction(actionPause)
} else if self.sessionTrack.sessionState == .Paused {
let actionResume = UIAlertAction(title: "Retomar", style: .Default) { [weak session = self.sessionTrack] (alert) in session!.resumeSession() }
commandsSheet.addAction(actionResume)
}
// Comando de habilitar/desabilitar vibração
let title = sessionTrack!.enableVibration ? "Desabilitar Vibração" : "Habilitar Vibração"
commandsSheet.addAction(UIAlertAction(title: title, style: .Default) { (alert) in self.sessionTrack!.enableVibration = !self.sessionTrack!.enableVibration })
// Outros comandos
commandsSheet.addAction(UIAlertAction(title: "Parar Sessão", style: .Destructive) { (alert) in self.dismissViewControllerAnimated(true, completion: nil) })
commandsSheet.addAction(UIAlertAction(title: "Cancelar", style: .Cancel, handler: nil))
// Usado como workaround com um bug do iOS 8
dispatch_async(dispatch_get_main_queue()) {
// Apresenta o commands sheet
self.presentViewController(commandsSheet, animated: true, completion: nil)
}
}
Exercício 9: Passando a atividade selecionada para a tela de Sessão
9.1. Crie um Segue do tipo Present Modally entre o View Controller de Início e o de Sessão
Modifique a propriedade identifier do Segue para StartSession.
9.2. Inclua uma seção para Action Metidos na classe NewSessionViewController
No arquivo NewSessionViewController.swift inclua uma seção para Action Methods conforme o código abaixo:
//
// MARK: - Action Methods
9.3. Crie um novo Action Method para o botão Iniciar Atividade
No arquivo NewSessionViewController.swift crie um novo Action Method a partir do botão Iniciar Atividade com o código abaixo:
@IBAction func startSession(sender: UIButton) {
if let _ = self.selectedActivity {
self.performSegueWithIdentifier("StartSession", sender: self)
} else {
// Se não tiver selecionado nenhuma atividade apresenta uma mensagem
let alertC = UIAlertController(title: "Traqt", message: "Selecione uma atividade para iniciar.", preferredStyle: UIAlertControllerStyle.Alert)
alertC.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(alertC, animated: true, completion: nil)
}
}
9.4. Inclua a implementação do método prepareForSegue:vender:
No arquivo NewSessionViewController.swift inclua a implementação do método conforme o código abaixo:
//
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "StartSession" {
let destVC = segue.destinationViewController as! SessionViewController
destVC.activity = self.selectedActivity
}
}
Exercício 10: Alterando a cor da barra de status
10.1. Alterar a cor da barra de Status no Designer do Storyboard
10.2. Inclua o código para alterar a cor da barra de status
No arquivo SessionViewController.swift inclua o código abaixo:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}