Um clone do Instagram usando SwiftUI e GraphQL – ProfileView

Hoje, na parte 3 do nosso aplicativo clone do Instagram com GraphQL, vamos nos aprofundar na SwiftUI, criando nossa visualização de perfil.

Aprenderemos a reutilizar structs na SwiftUI e discutiremos alguns controles: VStack, HStack, GeometryReader, Text, Button, Spacer, Image, Divider, entre outros.

Em nossos artigos anteriores, aprendemos como registrar um usuário e como fazer login em um usuário, com as respectivas UIs em nosso aplicativo clone do Instagram. Hoje vamos tornar isso muito mais agradável.

Aperte os cintos de segurança e vamos lá!

Para um melhor aprendizado, faça o download do projeto iOS Instagram Clone com o código-fonte.

Deseja um início rápido?

Clone esse aplicativo em nosso Hub e comece a usá-lo sem problemas!

O que exatamente estaremos criando

Criaremos a seguinte visualização:

screen-shot-2019-09-16-at-10-08-35

O SwiftUI facilita muito a criação de interfaces complexas, pois você pode reutilizar muitos componentes de forma muito fácil e direta.

O único problema é que precisamos aprender a criar esses componentes reutilizáveis. Essa única exibição é, na verdade, uma combinação de várias exibições que se integram em um resultado final.
Uma lista simplificada de componentes é a seguinte:

screen-shot-2019-09-16-at-10-08-35

Onde:

  • VStack
  • Hstack
  • Controles reais (botões, divisores, etc.)

HStack, Vstack, Zstack o quê?

O SwiftUI constrói suas interfaces de usuário alinhando as visualizações verticalmente usando o VStack (Vertical Stack) e horizontalmente usando o HStack (Horizontal Stack) e sobrepondo as visualizações com o Zstack (Z como em z-index).

Sempre que precisar de uma visualização embaixo de outra, você deve usar um VStack.

Sempre que precisar de uma visualização ao lado de outra, use o HStack.

Toda vez que precisar de uma visualização sobreposta a outra, você deve usar um ZStack.

Como nossa visualização principal consistirá em várias visualizações, uma colocada horizontalmente sob a outra, conteremos tudo na VStack principal e começaremos a partir dela, mas há mais uma que precisaremos usar para ocupar a tela inteira: o GeometryReader.

Ele nos permite renderizar tudo como uma função de seu tamanho e coordenadas (do GeometryReader).

Reutilização

A reutilização é uma das belezas da SwiftUI, de modo que podemos criar controles complexos e reutilizá-los onde for necessário.

Para este aplicativo, há principalmente dois componentes que reutilizaremos em diferentes exibições: a linha do tempo e a barra inferior:

screen-shot-2019-09-16-at-10-46-23

Por esse motivo, criaremos esses códigos de interface do usuário separadamente para que fiquem mais organizados. Todos os outros códigos de interface do usuário específicos de uma visualização podem ficar no arquivo de código dessa visualização.

Então, vamos começar…

Criando nossa visualização de perfil

Adicione um novo arquivo SwiftUI e nomeie-o ProfileView.swift.

Como alinharemos os componentes para preencher a tela, vamos começar adicionando um GeometryReader para que possamos garantir que todos os controles dentro dele usarão seu tamanho e suas coordenadas:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            
        }
    }
}

Agora, nossa visualização será incorporada a uma VStack principal que conterá todos os nossos controles, portanto, vamos adicioná-la também

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack{
                
            }
        }
    }
}

E a nossa primeira “linha” de controles será a superior:

screen-shot-2019-09-16-at-10-53-00

O que parece ser uma simples linha de controles é, na verdade, vários controles:

  • o texto “username” (nome de usuário)
  • a pequena seta apontando para baixo ao lado dele
  • um espaçador para preencher o espaço entre essa pequena seta e o próximo controle
  • um botão Hamburger à direita

Usaremos ícones para os botões, portanto, certifique-se de encontrar alguns ícones gratuitos. Um bom lugar para encontrá-los é o Freepik.

Então, vamos adicionar nosso HStack:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack{
                HStack{
                    
                }
            }
        }
    }
}

E nele, nosso primeiro Text:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack{
                HStack{
                    Text("nome de usuário")
                }
            }
        }
    }
}

Até agora, isso provavelmente o trouxe até aqui:

screen-shot-2019-09-16-at-10-59-56

Tudo bem. É um começo.

Vamos alinhá-lo ao lado esquerdo adicionando um

(alinhamento: .leading)

ao nosso VStack:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                }
            }
        }
    }
}

Também podemos adicionar algumas propriedades de texto para torná-lo mais consistente com nosso design:

Para definir sua cor como lightBlueColor, que é definida em nosso AppDelegate:

.foregroundColor(lightBlueColor)

Para alterar a espessura da fonte:

.fontWeight(.semibold)

E, finalmente, para adicionar um pouco de preenchimento (espaço) no lado principal:

.padding(.leading, 10)

E seu código agora deve ter a seguinte aparência:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                    .fontWeight(.semibold)
                    .padding(.leading, 10)
                }
            }
        }
    }
}

E sua interface do usuário deve se parecer com isso:

screen-shot-2019-09-16-at-11-07-31

Agora vamos adicionar o pequeno botão de seta.

Como você aprendeu na Parte 2 deste artigo, adicione a imagem da seta para baixo ao nosso botão e vamos adicionar o botão ao nosso código SwiftUI:

Button(action: {}){
    
}

E adicione nossa imagem a ele:

Button(action: {}){
    Imagem("seta para baixo")
    .redimensionável()
    .frame(width: 10, height: 10)
}

E, apenas para fins de alinhamento, vamos adicionar um pouco de preenchimento na parte superior:

Button(action: {}){
    Imagem("seta para baixo")
    .redimensionável()
    .frame(width: 10, height: 10)
}
.padding(.top, 5)

Nosso código completo agora deve ser assim:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                    .fontWeight(.semibold)
                    .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                }
            }
        }
    }
}

E nossa interface do usuário:

screen-shot-2019-09-16-at-11-28-48

Agora vamos adicionar o botão de hambúrguer da mesma forma:

Botão(ação: {}){
    Imagem("menu")
    .redimensionável()
    .frame(width: 20, height: 20)
}.padding()

Nosso código completo:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                    .fontWeight(.semibold)
                    .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                }
            }
        }
    }
}

E nossa visualização:

screen-shot-2019-09-16-at-11-31-17

Se ao menos houvesse algo que pudéssemos colocar entre esses dois botões para ocupar todo o espaço entre eles e alinhar tudo…

Espaçador()

Agora está bonito!

Nosso código completo até agora:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                    .fontWeight(.semibold)
                    .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Espaçador()
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                }
            }
        }
    }
}

E agora vamos apenas corrigir a altura desse HStack e dar a ele algum preenchimento no lado da frente, e estamos prontos para começar:

.frame(height: 50)
.padding(.leading, 10)

Código completo:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                    .fontWeight(.semibold)
                    .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Espaçador()
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                }.frame(height: 50)
                .padding(.leading, 10)
            }
        }
    }
}

Agora podemos começar nosso…

Segundo HStack

Como criamos tudo dentro de um VStack principal, cada novo controle que adicionarmos fora desse primeiro HStack será automaticamente colocado sob ele.

Portanto, é hora de fazer nosso segundo HStack e construir a segunda parte da nossa tela:

screen-shot-2019-09-16-at-12-01-35

Esse também será um HStack, contendo 4 VStacks em seu interior: um para a imagem e o texto abaixo dela, e 3 para os números com texto abaixo deles.

Como você provavelmente já entendeu o conceito, vou deixar o código completo para esse novo HStack:

HStack{
    VStack{
        Imagem("logo-social")
        .redimensionável()
        .frame(width: 90, height: 90)
            .clipShape(Circle())
            .shadow(radius: 3)
            .overlay(Circle().stroke(Color.pink, lineWidth: 1))
        
        Text("Seu nome")
            .foregroundColor(lightBlueColor)
            .fontWeight(.semibold)
    }.padding(.leading, 10)
    
    VStack{
        Text("10")
        .font(.system(size: 30))
        .foregroundColor(lightBlueColor)
        .fontWeight(.bold)
        
        Texto ("Publicações")
        .font(.system(size: 13))
        .foregroundColor(lightBlueColor)
    }.padding(.leading, 30)
    
    VStack{
        Text("100")
        .font(.system(size: 30))
        .foregroundColor(lightBlueColor)
        .fontWeight(.bold)
        
        Texto ("Seguidores")
        .font(.system(size: 13))
        .foregroundColor(lightBlueColor)
    }.padding()
    
    VStack{
        Texto("1000")
        .font(.system(size: 30))
        .foregroundColor(lightBlueColor)
        .fontWeight(.bold)
        
        Texto ("Following")
        .font(.system(size: 13))
        .foregroundColor(lightBlueColor)
    }
    
}.frame(height: 100)
.padding(.leading, 10)

E nosso código completo seria:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                        .fontWeight(.semibold)
                        .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Espaçador()
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                    
                }.frame(height: 50)
                .padding(.leading, 10)
                
                HStack{
                    VStack{
                        Imagem("logo-social")
                        .redimensionável()
                        .frame(width: 90, height: 90)
                            .clipShape(Circle())
                            .shadow(radius: 3)
                            .overlay(Circle().stroke(Color.pink, lineWidth: 1))
                        
                        Text("Seu nome")
                            .foregroundColor(lightBlueColor)
                            .fontWeight(.semibold)
                    }.padding(.leading, 10)
                    
                    VStack{
                        Text("10")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Publicações")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding(.leading, 30)
                    
                    VStack{
                        Text("100")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Seguidores")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding()
                    
                    VStack{
                        Texto("1000")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Following")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }
                    
                }.frame(height: 100)
                .padding(.leading, 10)
            }
        }
    }
}

Portanto, nossa visualização terá a seguinte aparência:

screen-shot-2019-09-16-at-12-06-17

Legal!

Adição do botão Editar perfil e do divisor

Seria tentador pensar que o botão Edit Profile e o Divider abaixo dele deveriam estar em uma VStack:

screen-shot-2019-09-16-at-13-29-27

Mas isso não é realmente necessário, pois toda a nossa visualização está dentro da nossa VStack principal, portanto, podemos simplesmente adicioná-los ao nosso código:

 Button(action: {}){
    Texto("Editar perfil")
    .fontWeight(.bold)
    .foregroundColor(lightBlueColor)
}.frame(width: 400)
.padding()

Divisor()

que teria a seguinte aparência:

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                        .fontWeight(.semibold)
                        .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Espaçador()
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                    
                }.frame(height: 50)
                .padding(.leading, 10)
                
                HStack{
                    VStack{
                        Imagem("logo-social")
                        .redimensionável()
                        .frame(width: 90, height: 90)
                            .clipShape(Circle())
                            .shadow(radius: 3)
                            .overlay(Circle().stroke(Color.pink, lineWidth: 1))
                        
                        Text("Seu nome")
                            .foregroundColor(lightBlueColor)
                            .fontWeight(.semibold)
                    }.padding(.leading, 10)
                    
                    VStack{
                        Text("10")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Publicações")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding(.leading, 30)
                    
                    VStack{
                        Text("100")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Seguidores")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding()
                    
                    VStack{
                        Texto("1000")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Following")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }
                    
                }.frame(height: 100)
                .padding(.leading, 10)
                
                Botão(ação: {}){
                    Texto("Editar perfil")
                    .fontWeight(.bold)
                    .foregroundColor(lightBlueColor)
                }.frame(width: 400)
                .padding()
                
                Divider()
            }
        }
    }
}

e nossa UI:

screen-shot-2019-09-16-at-13-34-15

Simulando nossa linha do tempo

Nossa visualização da linha do tempo será usada em outras partes do aplicativo, portanto, faz sentido dividi-la em um arquivo diferente.
Ela poderia ser reutilizada de dentro do ProfileView da mesma forma, mas isso mantém as coisas mais organizadas quando dividimos o código.

Crie um arquivo TimelineView.swift.

Há muitas maneiras diferentes de exibir dados na SwiftUI, mas escolhi essa para o meu aplicativo:

  • Nossa visualização de linha do tempo é um VStack de LineViews
  • Cada LineView é um HStack composto por 3 PreviewViews
  • Cada PreviewView tem uma imagem dentro dele

screen-shot-2019-09-16-at-13-29-27-copy-2

A primeira coisa que farei é criar um struct para armazenar nossos dados. Chamarei essa estrutura de Preview e ela terá dois parâmetros: um id (tipo Int) para iterar e um imageURL (tipo String) que conterá o URL de uma imagem que estarei passando:

struct Preview {
    var id: Int
    let imageUrl: String
}

Como eu disse, você poderia escolher outra forma de exibir seus dados, mas achei isso muito fácil de entender, então vamos adicionar a estrutura para nosso PreviewView primeiro.
Nossa estrutura tem uma propriedade Preview que definirei mais tarde, mas usaremos a propriedade imageURL para renderizar a imagem:

struct PreviewView: View {
    let preview: Preview
    
    var body: some View {
        Imagem (preview.imageUrl)
        .redimensionável()
        .frame(width: 136, height: 136)
    }
}

Com isso feito, podemos adicionar a estrutura para nosso LineView, que recebe uma matriz de 3 visualizações para exibir na linha.
Vou mudar isso no futuro para refletir dados reais, mas, por enquanto, está tudo bem:

struct LineView: View {
    let previewArray:[Preview]
    
    var body: some View {
        HStack(spacing: 2){
            PreviewView(preview: previewArray[0])
            PreviewView(preview: previewArray[1])
            PreviewView(preview: previewArray[2])
        }
    }
}

Por fim, podemos criar uma matriz de objetos Preview que percorreremos em loop:

let previews:[Preview] = [
    Preview(id: 0, imageUrl: "1"),
    Preview(id: 1, imageUrl: "2"),
    Preview(id: 2, imageUrl: "3"),
    Preview(id: 3, imageUrl: "4"),
    Preview(id: 4, imageUrl: "5"),
    Preview(id: 5, imageUrl: "6"),
    Preview(id: 6, imageUrl: "7"),
    Preview(id: 7, imageUrl: "8"),
    Preview(id: 8, imageUrl: "9"),
    Preview(id: 9, imageUrl: "10"),
    Preview(id: 10, imageUrl: "11"),
    Preview(id: 11, imageUrl: "12"),
    Preview(id: 12, imageUrl: "13")
]

Essa matriz tem 13 objetos e eu referenciei as imagens que usarei com nomes de 1 a 13. Também salvei essas imagens na minha pasta Assets, mas, novamente, mudarei isso no futuro:

screen-shot-2019-09-16-at-14-06-55

Agora que já temos tudo pronto, podemos iterar pela nossa matriz e criar nosso LinePreviews passando 3 objetos de visualização para ele.
Observe que estou passando o mesmo objeto, mas, mais uma vez, isso é temporário para exibição e será alterado:

var body: some View {
        ScrollView{
            VStack(alignment: .leading, spacing: 2){
                ForEach(previews, id: \.id) { preview in
                    LineView(previewArray: [preview, preview, preview])
                }
            }
        }
}

Portanto, nosso código completo seria algo como isto:

struct TimelineView: View {
    
    let previews:[Preview] = [
        Preview(id: 0, imageUrl: "1"),
        Preview(id: 1, imageUrl: "2"),
        Preview(id: 2, imageUrl: "3"),
        Preview(id: 3, imageUrl: "4"),
        Preview(id: 4, imageUrl: "5"),
        Preview(id: 5, imageUrl: "6"),
        Preview(id: 6, imageUrl: "7"),
        Preview(id: 7, imageUrl: "8"),
        Preview(id: 8, imageUrl: "9"),
        Preview(id: 9, imageUrl: "10"),
        Preview(id: 10, imageUrl: "11"),
        Preview(id: 11, imageUrl: "12"),
        Preview(id: 12, imageUrl: "13")
    ]
    
    var body: some View {
            ScrollView{
                VStack(alignment: .leading, spacing: 2){
                    ForEach(previews, id: \.id) { preview in
                        LineView(previewArray: [preview, preview, preview])
                    }
                }
            }
    }
}

struct TimelineView_Previews: PreviewProvider {
    static var previews: some View {
        TimelineView()
    }
}

struct Preview {
    var id: Int
    let imageUrl: String
}

struct LineView: View {
    let previewArray:[Preview]
    
    var body: some View {
        HStack(spacing: 2){
            PreviewView(preview: previewArray[0])
            PreviewView(preview: previewArray[1])
            PreviewView(preview: previewArray[2])
        }
    }
}

struct PreviewView: View {
    
    let preview: Preview
    
    var body: some View {
        Image(preview.imageUrl)
        .redimensionável()
        .frame(width: 136, height: 136)
    }
}

E se o chamarmos em nosso ProfileView.swift logo abaixo do nosso Divider:

...
 Botão(ação: {}){
    Texto("Editar perfil")
    .fontWeight(.bold)
    .foregroundColor(lightBlueColor)
}.frame(width: 400)
.padding()

Divisor()

TimelineView().padding(.leading, 10)

...

Também podemos adicionar outro Divider logo abaixo dele para que tenhamos quase o resultado final que desejamos:

...
 Botão(ação: {}){
    Texto("Editar perfil")
    .fontWeight(.bold)
    .foregroundColor(lightBlueColor)
}.frame(width: 400)
.padding()

Divisor()

TimelineView().padding(.leading, 10)

Divisor()

...

Qual é a aparência?

screen-shot-2019-09-16-at-14-13-10

Já está bonito?

Vamos finalizar adicionando nosso…

Vista inferior

A visualização inferior será mais um arquivo, pois a usaremos em várias partes do aplicativo.

Crie seu arquivo BottomView.swift e, nele, crie um HStack (já que os botões estarão lado a lado) de 4 botões com Spacers entre eles. Não se esqueça dos ícones!

struct BottomView: View {
    var body: some View {
        HStack{
             Botão(ação: {}){
                 Imagem("home")
                 .redimensionável()
                 .frame(width: 30, height: 30)
             }.padding()
             
             Espaçador()
             
             Botão(ação: {}){
                 Imagem("search")
                 .redimensionável()
                 .frame(width: 30, height: 30)
             }.padding()
             
             Espaçador()
             
             Botão(ação: {}){
                 Imagem("plus-button")
                 .redimensionável()
                 .frame(width: 30, height: 30)
             }.padding()
             
             Espaçador()
             
             Botão(ação: {}){
                 Imagem("coração")
                 .redimensionável()
                 .frame(width: 30, height: 30)
             }.padding()
             
             Espaçador()
             
             Botão(ação: {}){
                 Imagem("usuário")
                 .redimensionável()
                 .frame(width: 30, height: 30)
             }.padding()
        }.frame(height: 35)
    }
}

Isso foi fácil! Vamos integrá-lo ao nosso ProfileView.swift, logo abaixo do nosso último Divider:

...
Divider()
                
TimelineView().padding(.leading, 10)
                
Divisor()
                
BottomView()
...

Portanto, nosso código completo do ProfileView seria

importar SwiftUI

struct ProfileView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading){
                HStack{
                    Text("nome de usuário")
                    .foregroundColor(lightBlueColor)
                        .fontWeight(.semibold)
                        .padding(.leading, 10)
                    
                    Botão(ação: {}){
                        Imagem("seta para baixo")
                        .redimensionável()
                        .frame(width: 10, height: 10)
                    }
                    .padding(.top, 5)
                    
                    Espaçador()
                    
                    Botão(ação: {}){
                        Imagem("menu")
                        .redimensionável()
                        .frame(width: 20, height: 20)
                    }.padding()
                    
                }.frame(height: 50)
                .padding(.leading, 10)
                
                HStack{
                    VStack{
                        Imagem("logo-social")
                        .redimensionável()
                        .frame(width: 90, height: 90)
                            .clipShape(Circle())
                            .shadow(radius: 3)
                            .overlay(Circle().stroke(Color.pink, lineWidth: 1))
                        
                        Text("Seu nome")
                            .foregroundColor(lightBlueColor)
                            .fontWeight(.semibold)
                    }.padding(.leading, 10)
                    
                    VStack{
                        Text("10")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Publicações")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding(.leading, 30)
                    
                    VStack{
                        Text("100")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Seguidores")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }.padding()
                    
                    VStack{
                        Texto("1000")
                        .font(.system(size: 30))
                        .foregroundColor(lightBlueColor)
                        .fontWeight(.bold)
                        
                        Texto ("Following")
                        .font(.system(size: 13))
                        .foregroundColor(lightBlueColor)
                    }
                    
                }.frame(height: 100)
                .padding(.leading, 10)
                
                Botão(ação: {}){
                    Texto("Editar perfil")
                    .fontWeight(.bold)
                    .foregroundColor(lightBlueColor)
                }.frame(width: 400)
                .padding()
                
                Divisor()
                
                TimelineView().padding(.leading, 10)
                
                Divisor()
                
                BottomView()
            }
        }
    }
}

struct ProfileView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileView()
    }
}

E finalmente…

Temos nosso ProfileView completo:

screen-shot-2019-09-16-at-10-08-35

Agora, como isso foi incrível!

Conclusão

Hoje você aprendeu a simular uma visualização de perfil em seu aplicativo. Ainda é apenas uma simulação, mas daremos a ela alguma funcionalidade com o tempo.

Você aprendeu a criar e a reutilizar componentes na SwiftUI e a usá-los de forma bonita para criar uma visualização complexa. Fantástico!

Criaremos algumas outras visualizações no próximo artigo!

Fique ligado!

Referência

Registre-se agora no Back4App e comece a criar seu aplicativo Instagram Clone.

Qual é a vantagem do SwiftUI?

Se você deseja criar clones, como o aplicativo Instagram, o SwiftUI fará a mágica.

– Ajuda na construção de interfaces complexas
– Reutilização de componentes
– O processo de reutilização de interfaces é simples e fácil

Você só precisa ter conhecimento para reutilizar esses componentes em conjunto.

O que é Hstack, Vstack e Zstack?

Esses nomes estão conectados devido à representação nos EUA. O SwiftUI constrói suas UIs com os seguintes padrões:

– A UI é construída verticalmente usando Pilha Vertical
– É construída horizontalmente usando pilha horizontal
– As visualizações sobrepostas são construídas com ZStack

Qual é o melhor recurso do SwiftUI?

O melhor recurso do SwiftUI é a reutilização. Você pode reutilizar os componentes repetidamente para criar as visualizações. Isso se aplica a todos os aplicativos. Você precisa saber como lidar com esses componentes.


Leave a reply

Your email address will not be published.