Uma das coisas mais difíceis para um desenvolvedor é escolher as cores que irão compor a interface dos aplicativos. Se você não for um designer a escolha das cores que combinem entre si ou a escolha de uma cor que se destaque sobre outra é uma tarefa bem difícil. Hoje irei falar sobre uma biblioteca que irá lhe auxiliar nestas escolhas. A biblioteca também possui outras funcionalidades úteis como uma palheta de cores flat e gerador de gradiente de cores.
A biblioteca em questão é Chameleon. Entre as principais funcionalidades do Chameleon podemos enumerar:
-
24 cores flat em duas tonalidades
As cores flat disponíveis são:
-
Contraste qualquer texto com o seu fundo
Funcionalidade que utilizaremos no nosso app para a geração de cores de contraste dos textos. Quando definimos uma cor de fundo para um
UIView
ela pode dificultar a leitura do texto. O Chameleon possui funções para gerar uma cor de texto que seja de fácil leitura.
Esta funcionalidade está disponível inclusive para a barra de status. -
Tema global do aplicativo
Uma funcionalidade bem interessante que está em fase beta. Ela não funcionou no nosso app porque o
UISegmentedControl
daUISearchBar
ficou invisível na cor de fundo. Mas é uma funcionalidade promissora. -
Escureça e clareie qualquer cor facilmente
O chameleon possui funções que lhe auxiliam na tarefa de escurecer e clarear cores pré-existentes.
-
Gere cores de imagens
Este recurso é muito útil para encontrar cores que combinem com imagens de fundo por exemplo. O Chameleon permite extrair esquemas de cores cores não flat, cores flat e a cor média da imagem.
-
Gere gradiente de cores facilmente
Gradiente de cor é um recurso muito utilizado como fundo de telas em aplicativos para iOS. Com o Chameleon a geração do gradiente é bastante simplificado e pode ser usado como cor de fundo, cor de fonte, etc.
-
Documentação Quick Help no Xcode
As funções do Chameleon são bem documentadas e podem ser acessadas através do Quick Help (Alt + Click) no Xcode.
-
Suporte a esquema de cor
A principal funcionalidade que iremos utilizar no nosso app será o esquema de cores. Com ele é possível escolher uma cor especifica que será utilizada no app e utilizar o gerador de esquema de cores do Chameleon para encontrar cores que combinem com a cor escolhida. O Chameleon gera cores flat e cores não flat.
O gerador de esquemas possui três classes disponíveis para geração de cores:Analogous Flat Color Scheme
Complementary Flat Color Scheme
Triadic Flat Color Scheme
-
Plugin de paleta de cores para o Storyboard do Xcode
O Chameleon disponibiliza um instalador para instalar a paleta de cores no OS X e ela fica disponível para ser utilizada no Xcode e em outros aplicativos que utilizem o color picker.
-
Suporte a cores Hex
O Chameleon possui funções muito úteis quando se trabalha com cores que foram geradas em css.
Para mais informações sobre outras funcionalidades do Chameleon consulte a página do projeto no GitHub.
Instalando o Chameleon
O Chameleon está disponível para ser instalada via CocoaPods através do comando pod 'ChameleonFramework/Swift'
. Iremos utilizar o aplicativo Lista de Pendências, desenvolvido neste post, para exemplificar a utilização do Chamaleon.
O arquivo Podfile da aplicação ficará conforme exemplo.
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
target 'ChameleonExample' do
# Comment this line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for ChameleonExample
pod 'DZNEmptyDataSet'
pod 'MGSwipeTableCell'
pod 'ChameleonFramework/Swift'
end
Após rodar o comando pod install
abra o workspace no Xcode. Para mais informações sobre o CocoaPods consulte este post.
Escolhi a cor Flat Sky Blue como cor primária da aplicação e utilizaremos os recursos do Chameleon para encontrar cores que combinem com o Azul para utilizarmos nos componentes visuais.
Crie um novo arquivo Appearance.swift
. Nele iremos utilizar a função ColorSchemeOf(_:color:isFlatScheme:)
para montar o nosso esquema de cores. Depois criaremos uma struct contendo as cores para serem utilizados no app.
//
// Appearance.swift
// ChameleonExample
//
// Created by Mateus Gustavo de Freitas e Silva on 04/07/16.
// Copyright © 2016 Mateus Gustavo de Freitas e Silva. All rights reserved.
//
import UIKit
import ChameleonFramework
private var colorArray = ColorSchemeOf(ColorScheme.Triadic, color: FlatSkyBlue(), isFlatScheme: true)
struct Color {
static let Primary = colorArray[2]
static let Secondary = colorArray[0]
static let Tertiary = colorArray[4]
}
Com as cores definidas iremos alterar a aparência dos componentes principais do app. Como queremos alterar todos os componentes utilizados no app vamos fazer isto na classe AppDelegate
.
Altere o método application(_:didFinishLaunchingWithOptions:)
para chamar o método customizeAppearance()
que criaremos a seguir.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
customizeAppearance()
return true
}
No método customizeAppearance()
iremos alterar o statusBarStyle para UIStatusBarStyleContrast
. Assim, o Chameleon irá escolher a melhor cor para contrastar com a nossa cor de fundo.
Em seguida iremos alterar a aparência dos componentes UINavigationBar
, UISearchBar
, UISegmentedControl
, UITabBar
, UITabBarItem
, UITableView
e UITableViewCell
utilizando a Struct Color
.
private func customizeAppearance() {
let navigationController = window?.rootViewController as! UINavigationController
navigationController.setStatusBarStyle(UIStatusBarStyleContrast)
UINavigationBar.appearance().barTintColor = Color.Secondary
UINavigationBar.appearance().titleTextAttributes = [ NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleTitle1), NSForegroundColorAttributeName: Color.Primary ]
UINavigationBar.appearance().tintColor = Color.Primary
UINavigationBar.appearance().translucent = false
UISearchBar.appearance().barTintColor = Color.Primary
UISegmentedControl.appearance().backgroundColor = Color.Primary
UISegmentedControl.appearance().tintColor = Color.Secondary
UITabBar.appearance().tintColor = Color.Secondary
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName : Color.Tertiary], forState: .Normal)
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName : Color.Secondary], forState: .Selected)
UITableView.appearance().backgroundColor = UIColor.whiteColor()
UITableView.appearance().tintColor = Color.Primary
UITableView.appearance().separatorColor = Color.Tertiary
UITableViewCell.appearance().backgroundColor = UIColor.whiteColor()
UITableViewCell.appearance().tintColor = Color.Primary
UITextField.appearance().tintColor = Color.Tertiary
}
Iremos alterar os métodos do protocolo DZNEmptyDataSetSource
para utilizar as cores definidas no Struct Color
. Primeiramente altere o método titleForEmptyDataSet(_:)
.
let attributes = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleTitle1), NSForegroundColorAttributeName: Color.Secondary, NSParagraphStyleAttributeName: paragraph]
Em seguido o método descriptionForEmptyDataSet(_:)
.
let attributes = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleBody), NSForegroundColorAttributeName: Color.Primary, NSParagraphStyleAttributeName: paragraph]
if !toDoList.isEmpty && searchBar.text!.characters.count > 0 {
attibutedString.addAttribute(NSForegroundColorAttributeName, value: Color.Tertiary, range: text.rangeOfString(searchBar.text!))
} else if !toDoList.isEmpty {
attibutedString.addAttribute(NSForegroundColorAttributeName, value: Color.Tertiary, range: text.rangeOfString(status))
}
Método imageTintColorForEmptyDataSet(_:)
.
func imageTintColorForEmptyDataSet(scrollView: UIScrollView!) -> UIColor! {
return Color.Tertiary
}
Método buttonTitleForEmptyDataSet(_:forState:)
let attributes = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleBody), NSForegroundColorAttributeName: Color.Primary]
No protocolo MGSwipeTableCellDelegate
o método swipeTableCell(_:swipeButtonsForDirection:swipeSettings:expansionSettings:)
.
let checkButton = MGSwipeButton(title: "", icon: UIImage(named:"clipboard-checked"), backgroundColor: UIColor.flatGreenColor())
checkButton.tintColor = UIColor(contrastingBlackOrWhiteColorOn: UIColor.flatGreenColor(), isFlat: true)
let editButton = MGSwipeButton(title: "", icon: UIImage(named: "clipboard-edit"), backgroundColor: UIColor.flatCoffeeColor())
editButton.tintColor = UIColor(contrastingBlackOrWhiteColorOn: UIColor.flatCoffeeColor(), isFlat: true)
let deleteButton = MGSwipeButton(title: "", icon: UIImage(named: "clipboard-remove"), backgroundColor: UIColor.flatRedColor())
deleteButton.tintColor = UIColor(contrastingBlackOrWhiteColorOn: UIColor.flatRedColor(), isFlat: true)
No protocolo UITableViewDelegate
inclua o método tableView(_:heightForHeaderInSection:)
. Neste método iremos retornar zero caso a lista esteja vazia ou o filtro seja diferente de Todas.
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if searchBar.selectedScopeButtonIndex == 2 && !toDoList.isEmpty {
return 28.0
} else {
return 0.0
}
}
Inclua também o método tableView(_:viewForHeaderInSection:)
. Infelizmente não existe um método para editar o label do header. Temos que criar a view inteira e retorna-la no método.
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if searchBar.selectedScopeButtonIndex == 2 {
let header = UILabel()
header.font = UIFont.preferredFontForTextStyle(UIFontTextStyleTitle3)
header.textColor = Color.Secondary
header.backgroundColor = Color.Primary
header.text = tableView.dataSource!.tableView!(tableView, titleForHeaderInSection: section)
header.sizeToFit()
let viewRect = CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.sectionHeaderHeight)
let view = UIView(frame: viewRect)
view.backgroundColor = Color.Primary
view.addSubview(header)
header.translatesAutoresizingMaskIntoConstraints = false
header.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 8.0).active = true
header.trailingAnchor.constraintGreaterThanOrEqualToAnchor(view.trailingAnchor, constant: 8.0).active = true
header.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
return view
}
let viewRect = CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 0)
let view = UIView(frame: viewRect)
view.backgroundColor = Color.Primary
return view
}
E por último iremos alterar a nossa célula do tableView. Altere a classe ToDoItemTableViewCell
incluindo os métodos abaixo.
override func awakeFromNib() {
super.awakeFromNib()
customizeAppearance()
}
private func customizeAppearance() {
itemLabel.textColor = Color.Primary
checkedButton.tintColor = Color.Tertiary
}
Não se esqueça de incluir a referência a biblioteca Chameleon onde for necessário.
import ChameleonFramework
Conclusão
A biblioteca Chameleon disponibiliza várias cores flat para serem utilizadas nos aplicativos iOS. A paleta de cores no Xcode facilita ainda mais o trabalho possibilitando a visualização diretamente no Storyboard. Há também outros recursos que são bastante úteis como a criação de cores através de código hex, geração de cor através de imagem, entre outros.
A seguir irei mostrar alguns exemplos de esquemas de cores gerados pelo Chameleon.O intuito não é definir ancores finais do app e sim mostrar o recurso de geração de esquema de cores.
Triadic Flat Color Scheme
Analogous Flat Color Scheme
Complementary Flat Color Scheme
Se tiver alguma dúvida, crítica ou sugestão deixe seu comentário abaixo. Se quiser entrar em contato pode me chamar no Twitter @mateusfsilva. Se gostou do post compartilhe.