Este post também está disponível em: Inglês, Japonês, Russo
Nota do Ray: Parabéns, pessoal, vocês conseguiram! Ajudando a divulgar o iOS 5 Feast, vocês liberaram mais cedo o primeiro tutorial sobre iOS 5! Aproveitem!
Postado pelo membro do Time de Tutoriais iOS Steve Baranski, fundador da komorka technology, uma provedora de serviços de consultoria e desenvolvimento iOS.
Para fazer sucesso na App Store, seu app precisa se destacar. O “look and feel” café com leite da interface provida pela Apple já não ajuda muito em um mercado tão competitivo.
A maioria dos aplicativos mais populares na App Store apresentam elementos de interface customizados:
- O Twitter implementou uma UITabBar customizada
- No Instagram ambas UITabBar e UINavigationBar foram customizadas
- Já o Epicurious para iPad customizou elementos padrões da interface split-view
Antes do iOS 5, muitos desenvolvedores precisavam utilizar recursos pouco convencionais para alcançar algum resultado. Embora a abordagem mais recomendada fosse sobrescrever o método drawRect:, muitos recorriam ao temido método “swizzling”.
Mas com o iOS 5, os dias de escuridão acabaram! No iOS 5 foram incluídas novas APIs que permitem a fácil customização de vários elementos do UIKit.
Para mostrar algumas dessas novas APIs, nesse tutorial vamos transformar um aplicativo sobre viagens de surf, com uma interface padrão, em um app com um tema mais “praia”.
Para aproveitar ao máximo esse tutorial, você precisa saber o básico sobre desenvolvimento iOS. Se você é novo na área, dê uma olhada nos outros tutoriais do site.
Vamos lá!
Para começar, faça o download do projeto inicial. Eu criei um app simples para você começar, assim podemos focar no assunto principal desse tutorial – a customização do UIKit.
Uma vez aberto o projeto, dê uma olhada pelo código e nos arquivos XIBs. Você vai ver que a view principal apresenta uma lista das nossas viagens, e a view de detalhes permite adicionar informações sobre cada viagem individualmente.
Nesse contexto, execute (“Build & Run”) o aplicativo (ou Cmd-R) para ver o que temos até agora.

Bom, tudo funcionando, mas dificilmente representa a experiência que teríamos em uma viagem para surfar, não parece divertido. Então vamos olhar com mais calma.
Vamos começar com a view de detalhes. Tudo parece bem simples, né?
Um botão (UIBarButtonItem) com estilo simples na barra de navegação no topo (UINavigationBar), simples elementos UITabBar e as tradicionais entradas de dados, incluindo:
- UILabels com a fonte padrão do sistema, a Helvetica
- UITextField
- UISlider
- UISwitch
- UISegmentedControl
Nesse tutorial, vamos customizar totalmente a view de detalhes usando a nova API do iOS 5. Então, com a ideia que temos em mente, vamos fazer esse aplicativo ficar diferente.
Adicionando uma imagem como background
Abrindo a pasta “Images” do projeto, você vai ver que já temos algumas imagens para usar na customização do nosso app – precisamos modificar o código para que possamos usá-las.
Dentro da pasta de imagens há um arquivo chamado “bg_sand.png”. Vamos começar colocando essa imagem como background da view de detalhes.
Abra o arquivo DetailViewController.m e crie o método viewDidLoad como abaixo:
- (void)viewDidLoad { [super viewDidLoad]; [[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_sand"]]]; } |
Se você ficou confuso, não esquenta. É a técnica usada para colocar imagens como plano de fundo, pois é um jeito fácil de adicionar imagens como background em uma view. Não há uma propriedade “backgroundImage”, mas há uma propriedade “backgroundColor”!
Execute o projeto para ver como ficou:

Já dá até para sentir a areia nos pés!
Customizando a UINavigationBar
Ainda na pasta de imagens, há duas imagens que vamos usar para customizar a barra de navegação (UINavigationBar): surf_gradient_textured_32.png e surf_gradient_textured_44.png.
Vamos repetir a imagem, da esquerda para a direita, por toda a barra de navegação. Existem dois tamanhos diferentes para a altura da imagem porque a altura da UINavigationBar varia de acordo com a posição do telefone, nesse caso, no modo landscape.
O iOS 5 oferece duas APIs para nos ajudar nessa tarefa:
- UINavigationBar possui uma nova propriedade backgroundImage que nos ajuda a definir a imagem de fundo (background).
- UIImage possui um novo método chamado resizableImageWithCapInsets, usado para criar imagens redimensionáveis. O método permite especificar quais partes da imagem que não serão redimensionadas, como um botão com cantos arredondados nas bordas, que não devem ser repetidos.
Poderíamos fazer isso diretamente na view de detalhes usando as novas APIs para adicionar uma imagem como background, mas aí teríamos que fazer o mesmo procedimento em todas as outras views que poderíamos ter em nosso projeto!
Obviamente isso levaria um tempo. Pensando nisso, o iOS 5 oferece uma nova funcionalidade que permite customizar elementos de interface uma única vez, substituindo todos os outros elementos dentro do mesmo nível de hierarquia.
Assim, começando pela UINavigationBar, vamos usar o conceito do “appearance proxy” para customizar alguns elementos que vão se repetir em todo o aplicativo.
Vamos dar uma olhada em como vai ficar nosso código. No arquivo SurfsUpAppDelegate.m, crie um novo método logo acima de application:didFinishLaunchingWithOptions:
- (void)customizeAppearance { // Criando imagens redimensionáveis UIImage *gradientImage44 = [[UIImage imageNamed:@"surf_gradient_textured_44"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; UIImage *gradientImage32 = [[UIImage imageNamed:@"surf_gradient_textured_32"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; // Definindo a imagem de background para *todas* as UINavigationBars [[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone]; // Customizando o texto do título para *todas* as UINavigationBars [[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0], UITextAttributeTextColor, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8], UITextAttributeTextShadowColor, [NSValue valueWithUIOffset:UIOffsetMake(0, -1)], UITextAttributeTextShadowOffset, [UIFont fontWithName:@"Arial-Bold" size:0.0], UITextAttributeFont, nil]]; } |
Nas duas primeiras linhas criamos uma imagem redimensionável usando o método resizableImageWithCapInsets. Note que esse método substitui stretchableImageWithLeftCapWidth:topCapHeight:, que agora é obsoleto.
No “cap insets”, você basicamente especifica uma parte fixa da imagem, nessa ordem: top, left, bottom, right (em cima, à esquerda, em baixo e à direita). O restante é redimensionado ao longo do elemento onde a imagem é aplicada. Nessa imagem em particular, queremos que tudo seja redimensionado, por isso colocamos 0 (zero) para todas as posições.
Nas duas linhas seguintes usamos o “appearance proxy”, definindo as imagens redimensionáveis como background, para as métricas indicadas da barra.
A última linha customiza o título que aparece na nossa view de detalhes. Para fazer isso, passamos um dicionário (NSDictionary) com os atributos para o texto. As chaves disponíveis são:
- UITextAttributeFont
- UITextAttributeTextColor
- UITextAttributeTextShadowColor
- UITextAttributeTextShadowOffset
Quase lá! Adicione agora apenas a linha abaixo no método application:didFinishLaunchingWithOptions, antes de qualquer código, para chamar o método de customização que criamos:
[self customizeAppearance]; |
Execute o aplicativo, e poderemos ver a UINavigationBar com a imagem que adicionamos, em ambas as orientações (portrait e landscape). E com o título personalizado!

Customizando o UIBarButtonItem
Na pasta “Images”, procure pelos arquivos button_textured_24.png e button_textured_30.png. Vamos usá-las para customizar os botões que aparecem na UINavigationBar.
Vamos definir essas imagens como redimensionáveis também. É importante fazer isso porque a largura dos botões pode variar dependendo do tamanho do texto dentro dele.
Para os botões, não queremos que sejam redimensionados os primeiros 5 pixels à esquerda e os outros 5 à direita, por isso vamos definir left e right em 5. Os pixels entre eles vão ser redimensionados tanto quanto necessário para ajustar a largura do botão.
Vamos tentar! Vamos usar o “appearance proxy” para customizar os UIBarButtonItems uma só vez, como fizemos antes. Adicione o seguinte código no final do método customizeAppearance:
UIImage *button30 = [[UIImage imageNamed:@"button_textured_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)]; UIImage *button24 = [[UIImage imageNamed:@"button_textured_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)]; [[UIBarButtonItem appearance] setBackgroundImage:button30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UIBarButtonItem appearance] setBackgroundImage:button24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; [[UIBarButtonItem appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0], UITextAttributeTextColor, [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], UITextAttributeTextShadowColor, [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAttributeTextShadowOffset, [UIFont fontWithName:@"AmericanTypewriter" size:0.0], UITextAttributeFont, nil] forState:UIControlStateNormal]; |
Parece familiar? Criamos imagens redimensionáveis e as definimos como background dos botões para ambas as orientações portrait e landscape. Em seguida, formatamos o texto com a fonte “typewriter-style” que vimos no começo do tutorial.
O botão “Voltar” precisa de uma customização especial, porque ele possui um estilo diferente – parecendo uma seta. Dê uma olhada nas imagens: Imagesbutton_back_textured_24.png and Imagesbutton_back_textured_30.png.
Adicione o seguinte código ao final do método customizeAppearance para alterar o botão “Voltar”:
UIImage *buttonBack30 = [[UIImage imageNamed:@"button_back_textured_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)]; UIImage *buttonBack24 = [[UIImage imageNamed:@"button_back_textured_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)]; [[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; |
Note que usamos valores diferentes para o “cap inset”, porque a imagem do botão “Voltar” tem o lado esquerdo mais largo que não deve ser redimensionado. Repare também que há uma propriedade em UIBarButtonItem para “backButtonBackgroundImage”, que usamos aqui.
Execute o projeto, e você vai ver UIBarButtonItems bem legais e customizados na sua UINavigationBar!

Customizando a UITabBar
Para customizar a UITabBar, o iOS 5 possui uma API que permite adicionar uma imagem como background da toolbar, e uma imagem que indica um item selecionado. Dê uma olhada em Imagestab_bg.png e Imagestab_select_indicator.png para ver as imagens que usaremos.
Embora queiramos apenas uma UITabBar, outras, provavelmente, terão a mesma aparência que essa. Por isso, vamos customizá-la utilizando “appearance proxy” para ter efeito em todas as UITabBar.
Adicione o seguinte código ao final do método customizeAppearance:
UIImage *tabBackground = [[UIImage imageNamed:@"tab_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; [[UITabBar appearance] setBackgroundImage:tabBackground]; [[UITabBar appearance] setSelectionIndicatorImage: [UIImage imageNamed:@"tab_select_indicator"]]; |
Execute o aplicativo… Legal, né?! O background e a imagem que representa um item selecionado ficaram ótimos!!

OBS: Você ainda pode especificar imagens para os comportamentos “finished” e “unfinished” se você quiser modificar a forma como as imagens de “selecionado” e “não selecionado” aparecem.
Customizando o UISlider
Dê uma olhada em Imagesslider_minimum.png, Imagesslider_maximum.png, e Imagesthumb.png para ver as imagens com as quais vamos trabalhar para customizar o UISlider.
O iOS 5 tornou ridiculamente fácil a customização do UISlider apenas definindo as propriedades “maximumTrackImage”, “minimumTrackImage”, e “thumbImage”.
Vamos lá! Adicione o seguinte código ao final do método customizeAppearance:
UIImage *minImage = [[UIImage imageNamed:@"slider_minimum.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)]; UIImage *maxImage = [[UIImage imageNamed:@"slider_maximum.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)]; UIImage *thumbImage = [UIImage imageNamed:@"thumb.png"]; [[UISlider appearance] setMaximumTrackImage:maxImage forState:UIControlStateNormal]; [[UISlider appearance] setMinimumTrackImage:minImage forState:UIControlStateNormal]; [[UISlider appearance] setThumbImage:thumbImage forState:UIControlStateNormal]; |
Execute o aplicativo e veja como ficou nosso UISlider!

Customizando o UISegmentedControl
Vamos agora personalizar nosso UISegmentedControl. Agora é um pouco mais complicado, porque temos um background para o estado “selecionado” e outro para o “não selecionado”, bem como estados diferentes para as partes adjacentes (por exemplo, selecionado na esquerda, desmarcado na direita; selecionado na direita e desmarcado na esquerda; e desmarcado em ambos os lados).
Dê uma olhada nas imagens que vamos usar para entender melhor a ideia: Imagessegcontrol_sel.png, Imagessegcontrol_uns.png, Imagessegcontrol_sel-uns.png, e Imagessegcontrol_uns-uns.png.
Assim, adicione o código abaixo ao final do método customizeAppearance:
UIImage *segmentSelected = [[UIImage imageNamed:@"segcontrol_sel.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)]; UIImage *segmentUnselected = [[UIImage imageNamed:@"segcontrol_uns.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)]; UIImage *segmentSelectedUnselected = [UIImage imageNamed:@"segcontrol_sel-uns.png"]; UIImage *segUnselectedSelected = [UIImage imageNamed:@"segcontrol_uns-sel.png"]; UIImage *segmentUnselectedUnselected = [UIImage imageNamed:@"segcontrol_uns-uns.png"]; [[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; |
Execute o aplicativo. Agora nosso UISegmentedControl está completamente diferente!

Customizando o UISwitch
Até a data deste tutorial, não há um jeito fácil de personalizar o UISwitch. No entanto (como em muitos outros controles) é extremamente fácil alterar a cor através da propriedade tintColor.
Para garantir que abordamos diferentes formas de customização, vamos definir a propriedade “onTintColor” no próprio código. Você vai ver que em DetailViewController nós já temos um IBOutlet – rentSwitch – conectado em DetailView.xib.
Então, vamos adicionar o código abaixo para definir a propriedade “onTintColor” no método viewDidLoad, em DetailViewController:
[rentSwitch setOnTintColor:[UIColor colorWithRed:0 green:175.0/255.0 blue:176.0/255.0 alpha:1.0]]; |
Execute o aplicativo e veja a diferença no nosso UISwitch!

Estamos quase lá, mas ainda temos algumas coisas para ver. Precisamos alterar as labels e o background do UITextField.
Customizando uma UILabel
Abra o arquivo DetailView.xib para que possamos editá-lo usando o Interface Builder. Selecione a primeira label (“Your name”) na view principal. No painel à direita, selecione a aba “Attributes Inspector” e faça as seguintes alterações:
- Font: Custom
- Family: American Typewriter
- Style: Regular
- Size: 16
Faça o mesmo para as outras duas labels: “Experience Level” e “Rent a board?”.
Execute o aplicativo. Nossas labels estão ótimas!!

Customizando o UITextField
Nosso UITextField já foi definido para usar o estilo UITextBorderStyleLine. Aproveitando que ainda estamos no Interface Builder, vamos alterar a fonte para American Typewriter, Size 12, Regular. Olhando na aba “Identity Inspector”, veremos que o campo “Custom Class” foi definido para “UITextField – CustomTextField”. Se olharmos agora para o painel “Navigator”, à esquerda, há um grupo (diretório) chamado Custom Views, onde há uma classe do mesmo tipo.
Para adicionar o background, vamos sobrescrever o método drawRect:, como sendo outra técnica de customização.
Substitua a chamada para “super” com o seguinte código:
- (void)drawRect:(CGRect)rect { UIImage *textFieldBackground = [[UIImage imageNamed:@"text_field_teal.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15.0, 5.0, 15.0, 5.0)]; [textFieldBackground drawInRect:[self bounds]]; } |
Assim criamos uma imagem redimensionável e a desenhamos no retângulo definido pelos limites (bounds) da view (nosso UITextField). Agora vamos executar o aplicativo…

É isso, aí! Nossa página de detalhes está totalmente customizada!
Para onde ir agora?
Aqui temos o projeto de exemplo com todo o código do tutorial.
Se você quiser aprender mais sobre a customização de elementos do UIKit no iOS 5, dê uma olhada em nosso novo livro iOS 5 by Tutorials! O livro inclui um capítulo adicional em “User Interface Customization in iOS 5″, onde ensino como personalizar table views, popover controllers, e mais métodos avançados de customização.
Se você tiver algum comentário ou dúvida sobre a customização de elementos UIKit, junte-se ao nosso fórum de discussão abaixo!
Postado pelo membro do Time de Tutoriais iOS Steve Baranski, fundador da komorka technology, uma provedora de serviços de consultoria e desenvolvimento iOS.
iPhoneCategoria:
Português
English
日本語
Русский 






