Trabalhar com o modo de Exibição de Tabela Controladores de Swift

Escrito por Reinder de Vries, em 3 de agosto de 2020 em Desenvolvimento de aplicativos iOS

Trabalhar com o modo de Exibição de Tabela Controladores de Swift

neste tutorial eu vou mostrar a você passo-a-passo de como modo de exibição de tabela controladores de trabalho, e como você pode usá-los. Vamos entrar na gama completa de UITableViewController, mergulhando em Programação Orientada a objetos, delegação e os mecanismos de bastidores de vistas de mesa.

um controlador de visualização de tabela apresenta informação estruturada e repetível numa lista vertical. Você usa a classe UITableViewController na sua aplicação iOS para criar um controlador de visualização de tabela.

trabalhar com um controlador de visualização de tabela também significa trabalhar com alguns conceitos importantes de desenvolvimento do iOS, tais como subclassing, o padrão de design de delegação, e reutilizar vistas.

é importante para os desenvolvedores profissionais e práticos do iOS (você!) para dominar o trabalho com controladores de visão de mesa. Uma vez que você se acostumou a trabalhar em um componente UI multifacetado, como UITableViewController, outros aspectos mais complexos do desenvolvimento do iOS vai começar a fazer sentido também.Preparado? Vamos mergulhar!

  1. Como um modo de Exibição de Tabela Controlador Funciona
  2. a criação de uma Tabela Simples View Controller
  3. Codificação Da Tabela de Ver Controlador de Origem de Dados
  4. Fornecer Células para O modo de Exibição de Tabela Controlador
  5. Responder à Interação com o Usuário
  6. Ler Mais

Como um modo de Exibição de Tabela Controlador Funciona

Se você já usou algum aplicativo para iOS antes, você já usou o modo de exibição de tabela controladores de antes. São usados com frequência em aplicações iOS!

aqui está um exemplo de um controlador de visualização de tabela:

exemplo do controlador de visualização de tabela

um controlador de visualização de tabela normalmente tem estes componentes visíveis:

  • uma vista de tabela, que é o componente de interface do usuário, ou vista, que é mostrado na tela. Uma visão de tabela é uma instância da classe UITableView, que é uma subclasse de UIScrollView.
  • células de visualização de tabelas, que são as linhas ou vistas repetíveis, mostradas na janela de tabelas. Uma célula de visualização de tabela é uma instância de uma classe UITableViewCell, e essa classe é muitas vezes subclassificada para criar células personalizadas de visualização de tabela.

um controlador de visualização de tabela também depende do uso destes componentes, nos bastidores:

  • um delegado da tabela view, que é responsável por gerenciar o layout da tabela view e responder a eventos de interação do Usuário. Um delegado da tabela view é uma instância da classe UITableViewDelegate.
  • uma fonte de dados da tabela ver, que é responsável pela gestão dos dados numa tabela ver, incluindo as células e secções da tabela ver. Uma fonte de dados é uma instância da classe UITableViewDataSource.

um controlador de navegação é frequentemente usado em conjunção com um controlador de visualização de tabela para permitir a navegação entre a visualização de tabela e os controladores de visualização subsequentes, e para mostrar uma barra de navegação acima da vista de tabela.

a parte mais interessante de trabalhar com controladores de table view é o próprio controlador de table view! Como assim?Conhece a arquitectura Model-View-Controller? De acordo com a arquitetura Model-View-Controller, uma table view e uma table view cell são vistas, e um table view controller é um controller.

as vistas são responsáveis por mostrar a informação visivelmente ao utilizador, com uma interface de utilizador (IU). Os controladores são responsáveis pela implementação da lógica, gerenciamento de dados e tomada de decisões. Dito de forma diferente: você não pode ver um controlador, mas ele está lá, gerenciando o que você vê através de vistas.

quando você usa um controlador de visualização de tabela no seu aplicativo, você está subclassificando a classe UITableViewController. A classe UITableViewController é uma subclasse do controlador UIView.

aqui está a hierarquia de classes de um controlador de tabelas de exemplo que mostra informações de contacto:

  • um exemplo de ContactsTableViewController
    • subclasses UITableViewController
      • subclasses UIViewController

Conforme os princípios da Programação Orientada a Objeto (OOP), quando a classe RaceCar subclasses da classe Vehicle, ela herda as propriedades e funções da superclasse, como maxSpeed e drive().

a classe Vehicle é então Chamada de superclasse de RaceCar. Este princípio é chamado de herança.Confuso? Pode ser! Pensa assim.: para que o seu controlador table view funcione OK, você precisa herdar um monte de código, para que você não tenha que escrever todo esse código sozinho. A hierarquia de classes, e OOP, existe para estruturar essa herança.

Diagrama de classes do controlador de visualização de tabela

pode trabalhar com vistas de tabela sem usar um controlador de visualização de tabela. Basta adicionar um UITableView a um controlador de visualização, fornecê-lo com implementações das funções de Delegado de visualização de tabela e de fonte de dados, e você está feito.

a classe UITableViewController fornece implementações padrão destas funções de Delegado de visualização de tabela e de fonte de dados de visualização de tabela. Esse é um aspecto crucial de trabalhar com um controlador de vista de mesa!

como você verá nos próximos capítulos deste tutorial, vamos sobrepor essas funções com nossas próprias implementações. Podemos personalizar o controlador de visualização de mesa fazendo isso.

Aprenda como criar apps para iOS

Começar com o iOS 14 e Swift 5

Entrar para o meu curso de desenvolvimento iOS, e aprender a construir o grande iOS 14 apps com Swift 5 e Xcode 12.

configurar um controlador de visualização de tabela simples

tudo bem, vamos colocar tudo isso em prática. Nesta seção, vamos construir um simples controlador de mesa. Você vai implementar as funções necessárias para fazê-lo funcionar, e eu vou explicar como eles funcionam à medida que avançamos. Toca a mexer!

Você pode usar 3 abordagens diferentes de trabalhar com Interfaces de usuário no Xcode:

  1. a Criação de pontos de vista por meio de programação, por exemplo, a codificação por sua mão
  2. Configuração de Interfaces de usuário na Interface Builder e conectá-los com o código Swift via XIBs
  3. Configuração de Interfaces de usuário e suas transições no Interface Builder usando Storyboards
  4. (Tecnicamente, você pode usar SwiftUI também, mas como para o modo de exibição de tabela controladores, que está fora do escopo deste tutorial.)

é entediante e improdutivo codificar Ui à mão. Se você não tem cuidado com os Storyboards, eles acabam escondendo a complexidade do desenvolvedor. Vamos trabalhar com Storyboards, enquanto descobrimos exactamente como funcionam nos bastidores.

aqui está o que você vai fazer:

primeiro, criar um novo projeto Xcode via File → novo projeto→… Certifique-se de escolher o modelo do aplicativo, e escolher Storyboard para Interface e Delegado do aplicativo UIKit para o ciclo de vida.

depois, tome estas medidas:

  1. clique com o botão Direito do rato no projecto no Project Navigator e escolha o Novo Ficheiro…
  2. Escolha o Cacau Toque de Classe de modelo (iOS)
  3. Selecione UITableViewController para Subclasse de
  4. Nome da classe ContactsTableViewController
  5. não assinalar Também criar arquivo XIB
  6. Finalmente, clique em Avançar e salve o arquivo junto com os outros Swift arquivos

por último, fazer isso:

  1. Vá em Main.storyboard e remover o modo de Exibição existente Controlador de Cena
  2. Adicionar uma nova Tabela do Controlador de Visualização para o storyboard através da Biblioteca
  3. Com o modo de exibição de tabela controlador seleccionado, vá para a Atributos de Inspetor e assinale a Inicial do Controlador de Visualização de caixa de verificação
  4. Finalmente, ir para a Identidade do Inspetor e Classe de conjunto para ContactsTableViewController

Que é isso! Você agora tem um controlador de visualização de mesa dentro do storyboard do projeto, e você o conectou à classe ContactsTableViewController Swift.

Xcode table view controller set up

como adivinhou, a sua classe ContactsTableViewController é uma subclasse de UITableViewController. Você pode ver isso no arquivo Swift, no topo, na declaração de classe.

class ContactsTableViewController: UITableViewController { ···

esta sintaxe significa: a classe ContactsTableViewController é uma subclasse de UITableViewController.

quando carrega com o botão direito no “UITableViewController” enquanto mantém a chave de opção, pode ver na declaração da classe que UITableViewController é uma subclasse de UIViewController, e está em conformidade com os protocolos UITableViewDelegate e UITableViewDataSource.

 ver documentação do controlador de visualização de tabela no Xcode

essa é a potência do controlador de visualização de tabela! Ele não nos dá apenas os componentes individuais para fazer uma vista de tabela, O controlador também fornece uma implementação padrão. É por isso que subclassificamos UITableViewController, em vez de criar um controlador de vista vazio com uma vista de tabela.

neste ponto, você pode executar a sua aplicação com Command-R ou o botão Play, e ver o controlador de visualização de tabela vazia aparecer no ecrã.Por falar nisso, porquê? Ainda não codificámos nada! Isso porque o controlador de visualização de tabela tem uma implementação padrão, que apenas mostra células vazias na tela. Fixe!

controlador de visualização de tabela exemplo no simulador de iPhone

dependendo da sua versão do Xcode, nós usamos o delegado de cena para configurar o controlador de visualização inicial de seu projeto app. Saiba mais aqui: o Delegado de cena no Xcode

um XIB e um NIB são basicamente a mesma coisa – eles contêm informações de layout. Um XIB tem um formato XML, enquanto um NIB tem um formato binário. O XML é compilado para binário quando você constrói seu aplicativo, então é por isso que as funções do UIKit sempre fala sobre um “nib”, enquanto o Xcode sempre o chama de “xib”.

Coding the Table View Controller Data Source

Now that your table view controller has been set up, let’s bring it to life! Neste capítulo, vamos nos concentrar nas diferentes funções que você vai precisar implementar para fazer o seu controle table view funcionar.

como explicado anteriormente, estas funções ou pertencem ao delegado do controlador de visualização de tabela, ou à fonte de dados do controlador de visualização de tabela. Ambos os protocolos usam Delegação para personalizar a vista da tabela.

As funções mais importantes para UITableViewDataSource são:

  • numberOfSections(in:)
  • tableView(_:numberOfRowsInSection:)
  • tableView(_:cellForRowAt:)

Outras funções relevantes para UITableViewDelegate são:

  • tableView(_:didSelectRowAt:)
  • tableView(_:willDisplay:for:)

Você pode encontrar mais funções no Apple Developer Documentação para UITableViewDelegate e UITableViewDataSource.

adicionando os dados de contatos

você vai começar adicionando os dados de informações de contato para o controlador de visualização de tabela. Adicionar a seguinte propriedade à classe ContactsTableViewController :

let contacts:] = , , , , , , , , , , , , , , , , ]

é um rolodex que todos gostaríamos de ter, certo? É assim que funciona.:

  • o let contacts declara uma constante com nome contacts. Você adicionou isso como uma propriedade para a classe, então cada instância de classe tem acesso a esta constante ao longo do Código da classe.
  • o tipo de contacts é ] , que é uma matriz de matrizes de cordas. Você está essencialmente criando um array, do qual os itens são arrays de strings. (Um nome variável e seu tipo são separados por dois pontos :)
  • o código = atribui uma matriz literal a contacts, preenchido com os nomes e números de telefone de alguns bilionários.

em um ponto posterior, podemos usar o número de itens na matriz com contacts.count. E podemos obter nomes individuais e números de telefone com contacts e contacts, usando sintaxe subscrita.

registar uma classe de células da tabela ver

Antes de poder utilizar células num controlador da tabela ver, terá de as registar com a tabela ver. Você pode fazê-lo de duas maneiras:

  1. proporcionando uma vista de tabela célula de classe e um identificador
  2. proporcionando uma vista de tabela célula XIB e um identificador

Quando você estiver usando uma tabela personalizada vista célula, você provavelmente deseja registrar um XIB para isso. Quando você está usando as células predefinidas da tabela ver, ou alguma outra célula programática, você registra a classe. Vamos usar a aula, por agora!

aditar o seguinte código à função viewDidLoad() :

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

certifique-se de adicioná-lo abaixo da linha super.viewDidLoad(). Como você provavelmente sabe, a função viewDidLoad() faz parte do ciclo de vida do controlador view, e pertence à classe UIViewController.

está a sobrepor a função viewDidLoad() para responder a este evento no ciclo de vida de um controlador de visualização, para que possa configurar a sua vista depois de ter sido carregada. No nosso caso, estamos a usar a função para registar a célula table view.

quando regista uma célula da tabela view, também tem de indicar um identificador. Isto é simplesmente para associar a classe da célula com um nome que você pode usar mais tarde, quando descurando a célula em tableView(_:cellForRowAt:).Ainda estás comigo? Vamos continuar!

Implementing ” number ofsections (in:)”

the first delegate function we’re going to implement is numberOfSections(in:).

uma vista de tabela pode ter várias secções ou grupos. Cada grupo tem um cabeçalho que flutua no topo da linha vertical de células. Numa aplicação de contactos, podias agrupar os contactos por ordem alfabética. Isto é realmente feito no aplicativo de contatos no iPhone, onde os contatos são agrupados A-Z.

o aplicativo que estamos construindo tem apenas uma seção. Adicionar a seguinte função à classe:

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

simples, certo? A função retorna 1 quando chamada.

implementando ” tableView (_: number ofrowsinsection:)”

uma função similar é tableView(_:numberOfRowsInSection:). Em vez de fornecer o número de seções, ele fornece o número de linhas em uma seção. Como uma tabela mostra células em uma lista vertical, cada célula corresponde a uma linha na tabela.

o aplicativo que estamos construindo tem apenas uma seção, e que uma seção tem um número de itens igual ao número de itens na matriz contacts. Então, isso é contacts.count!

adicionar a seguinte função à classe:

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

vês como funciona? Nós simplesmente retornamos contacts.count. Se você adicionasse outro nome e número de telefone a contacts, ele apareceria bem na vista da tabela também.

compreender linhas e secções

a nossa aplicação de contactos é unidimensional, apenas mostra uma lista de nomes e números de telefone, e não utiliza grupos. Mas e se você tiver uma visão de tabela agrupada?

na maioria dos casos, sua fonte de dados, como o array contacts, também seria multidimensional. Você organizaria grupos no primeiro nível, e itens individuais no segundo nível, “abaixo” dos grupos.

- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...

o número de grupos é igual a countries.count, e o número de Países num único grupo é igual a countries.count, onde x é o índice de secção. Esse índice de secção é fornecido como parâmetro em tableView(_:numberOfRowsInSection:).Notou como estas duas funções têm um parâmetro chamado tableView? Isso faz parte do princípio de Programação Orientada a objetos. Você pode tecnicamente usar uma fonte de dados de visualização de tabela e delegar para personalizar várias visualizações de tabela. Você usaria o tableView para identificar com que tabela você está trabalhando.

Imagine que você tem um aplicativo de contatos que pode mostrar números de telefone pelo nome, ou números de telefone organizados pela empresa. Você pode implementar isso de várias maneiras, por exemplo, reutilizando seus controladores de table view. Ou se você quiser reutilizar o layout do seu aplicativo de contatos para exibir informações semelhantes, como restaurantes, locais ou nomes de usuário do Skype? É aí que entra o código de reutilização com OOP!

fornecendo células para o controlador de visualização de tabela

estamos a chegar lá! Vamos passar para a função mais importante de um controlador de visualização de tabela: tableView(_:cellForRowAt:).

vamos implementar a função antes de mergulhar em detalhes, mas há algumas coisas que você precisa entender sobre isso:

  • Quando é chamado de
  • o Que é um índice caminho é
  • Como ele re-utiliza células

Primeiro, adicione a seguinte função para o ContactsTableViewController classe:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}

Veja como funciona:

  • A função substitui sua superclasse implementação de UITableViewController. Já sabes como isso funciona, certo? Estamos a anular a implementação padrão e a substituir a nossa. Isso porque UITableViewController já implementou a tabela view delegate e a fonte de dados para nós.
  • como antes, a função tem um parâmetro tableView que podemos usar para identificar a visão da tabela que esta função é chamada.
  • outro parâmetro é indexPath, com rótulo de argumento cellForRowAt. O caminho do Índice identifica os índices da célula row e section. Mais sobre isso mais tarde.
  • o tipo de retorno da função é UITableViewCell. Isso é interessante. Esta função é chamada pelo controlador table view, cada vez que precisamos fornecer uma célula table view!

quando você percorre os contatos neste aplicativo, toda vez que uma célula precisa ser exibida na tela, a função tableView(_:cellForRowAt:) é chamada. Sempre! Vou prová-lo daqui a pouco.A seguir, vamos escrever o corpo da função. Adicionar o seguinte código dentro da função:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell

eis o que acontece:

  • primeiro, retiramos uma célula com um identificador. É exactamente o mesmo identificador que usamos Antes, ao registar a célula. Dessa forma, a visão da tabela sabe que tipo de célula queremos. A célula reduzida é atribuída à constante cell. Agora temos uma célula table view para trabalhar. Mais sobre a fila mais tarde.
  • então, imprimimos algumas informações para o Console. Isto é para que possamos ver quando esta função é chamada, quando o aplicativo é executado.
  • então, Atribuímos o nome do contacto ao texto desta célula da tabela ver. O contacts contém o valor do nome do contato, ao qual chegamos usando indexPath.row. Cada instância de UITableViewCell tem uma propriedade textLabel de UILabel, e cada etiqueta desse tipo tem uma propriedade text. Use-o para definir o texto no rótulo.Não se preocupe, vamos rever cada uma destas coisas em mais detalhes. Primeiro, vê se consegues correr a tua aplicação. Vês os nomes dos contactos? Você vê o resultado de depuração na consola? Tente deslocar a aplicação!

    Table view controller rows

    When is ” tableView (_: cellForRowAt:)” Called?

    se você executou a aplicação de contactos, e se jogou com a rolagem para cima e para baixo, você não pode deixar de notar que cada vez que você desloca, o resultado de depuração aparece na consola.

    cada vez que uma célula que não estava na tela antes de aparecer, a função tableView(_:cellForRowAt:) é chamada, e uma nova linha aparece no Console.

    quando se chama tableView(_:cellForRowAt:)? Toda vez que uma célula de visualização de mesa precisa ser mostrada na tela!

    o controlador de visualização de tabela determinou que uma célula é necessária, por isso chama tableView(_:cellForRowAt:). A nossa implementação dessa função retira uma célula, altera-a e devolve-a ao controlador de visualização de tabelas. O controlador de visualização de tabela, e o framework UIKit, então o torna graficamente na tela.

    o que é um caminho de índice?

    cada vez que o controlador de visualização de tabela precisa de uma célula de tableView(_:cellForRowAt:), ele fornece um caminho de índice como um argumento para a função. Dentro do corpo da função você pode usar o parâmetro indexPath para saber exatamente qual célula o controlador da tabela view precisa.

    um caminho de índice é como um endereço, ou uma coordenada em uma grade. Um grafo típico tem um eixo X e um eixo Y, então você pode expressar uma coordenada nesse grafo como x, y como 0, 1 e 42, 3. Da mesma forma, uma planilha tem linhas e colunas com índices.

    uma vista de tabela usa secções e linhas. Como discutido anteriormente, você pode usar seções para agrupar as células em conjunto. O nosso aplicativo tem apenas uma seção, e tem contacts.count linhas. As linhas da vista da tabela correm de cima para baixo.

    disse de forma diferente: as secções e linhas de uma tabela são o que as colunas e linhas são para uma folha de cálculo. Um caminho de índice define uma localização na área de tabela, usando uma linha e uma seção.

    as linhas e secções são representadas por números, chamados índices. Estes índices começam em zero, de modo que a primeira linha e secção terá o número de índice 0.

    quando você olha para trás para a imagem anterior, faz muito mais sentido. A primeira célula tem caminho de índice 0, 0, a segunda célula 0, 1, continuando até a última célula visível com caminho de índice 0, 11.

    the Table View Reuse Mechanism

    What’s most noteworthy about the table view is its mechanism for cell reuse. É muito simples, na verdade.

    • cada vez que um controlador de visualização de tabela precisa mostrar uma célula na tela, a função tableView(_:cellForRowAt:) é chamada, como já discutimos antes.
    • em vez de criar uma nova célula de visualização de tabelas cada vez que essa função é chamada, ela tira uma célula criada anteriormente de uma fila.
    • a célula reinicia para um estado vazio, limpa a sua aparência, e a célula é personalizada novamente em tableView(_:cellForRowAt:).Sempre que uma célula é desenrolada fora do ecrã, não é destruída. É adicionado à fila, à espera de ser reutilizado.É muito inteligente, não é? Em vez de criar e excluir células, você simplesmente reutilizá-las. Mas … porquê?

      é muito menos intensivo de memória reutilizar células. O controlador de visualização de tabela iria constantemente escrever para a memória ao criar e excluir células. Gerir a memória também seria mais intensivo. Quando as células são reutilizadas, a memória é usada mais eficientemente, e menos operações de memória são necessárias.

      também, itt é um pouco menos intensivo de CPU para reutilizar células em vez de criá-las e apagá-las, porque simplesmente há menos operações envolvidas na reutilização, em comparação com a criação e exclusão de células.

      quando se desloca rapidamente através de uma vista de tabela, não se vêem novas células – vê-se as mesmas células vezes sem conta, com novas informações.

      o código envolvido com a reutilização de células é este:

      let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)

      a função dequeueReusableCell(withIdentifier:) tenta retirar uma célula. Quando não há células na fila, ele irá criar uma célula para nós. O identificador é usado para manter cada tipo de célula em sua própria fila, e para se certificar de que a classe correta é usada para criar novas células.

      Aprenda como criar apps para iOS

      Começar com o iOS 14 e Swift 5

      Entrar para o meu curso de desenvolvimento iOS, e aprender a construir o grande iOS 14 apps com Swift 5 e Xcode 12.

      respondendo à interação do Usuário

      uma coisa está faltando do nosso controlador de visualização de tabela: a capacidade de chamar as pessoas em nossa lista de contatos! Mas antes de fazermos isso, vamos garantir que você também pode ver o número de telefone de um contato no controlador table view.

      a classe predefinida UITableViewCell tem 4 tipos diferentes, como expresso na enumeração UITableViewCellStyle. Você pode escolher entre:

      • .default – uma simples vista com uma linha de texto em preto
      • .value1 – uma simples vista com uma linha de texto em preto, à esquerda, e uma pequena etiqueta azul à direita (usados em Configurações do aplicativo)
      • .value2 – uma simples vista com uma linha de texto em preto sobre o direito, e uma pequena etiqueta azul à esquerda (usado no aplicativo de Contatos)
      • .subtitle – uma simples vista com uma linha de texto em preto, e uma pequena linha de texto em cinza abaixo

      a Maioria dos desenvolvedores utilizar a vista de tabela personalizada células esses dias, então você não vai ver estes tipos de células que, muitas vezes. Mas eles estão lá!

      temos de ajustar ligeiramente o código em tableView(_:cellForRowAt:). Substituir a primeira linha da função pelo seguinte código::

      var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}

      se olhar de perto, verá que removemos a parte for: indexPath da chamada dequeueReusableCell(...). Em vez disso, essa função agora retorna uma opcional. Quando não consegue retirar uma célula, a função retorna nil.

      então saltamos em nós mesmos para criar a célula, se for nil. Você vê isso na segunda parte do Código. Você usa uma declaração condicional if para verificar se cell é igual a nil, e se isso for verdade, você cria a célula usando o inicializador UITableViewCell(style:reuseIdentifier:).

      esse inicializador recebe dois argumentos, o estilo celular .subtitle, e o identificador que usamos anteriormente.

      neste momento temos um problema, porque cell é uma opção agora! Seu tipo é UITableViewCell?, mas o tipo de retorno da função exige que retornemos uma instância com tipo não opcional UITableViewCell.

      felizmente, este é um daqueles casos em que podemos usar a força de desembrulhamento para desembrulhar o valor opcional. Por causa da forma como o nosso código é escrito, é impossível para cell ser nil além do condicional. Você pode garantir que cell não é nil após a declaração if.

      certifique-se de atualizar a função para usar o desembrulhamento de força para cell. Além disso, adicione a seguinte linha de código abaixo cell!.textLabel ... para definir o subtítulo da célula mostrar o número de telefone do contato.

      cell!.detailTextLabel?.text = contacts

      toda a função agora se parece com esta:

      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}

      finalmente, certifique-se de remover a seguinte linha de viewDidLoad(). Impedirá a visualização da tabela de inicializar células com o tipo errado.Muito bem! Execute o seu aplicativo com o Comando + R ou o botão Play, e verifique se ele funciona. Vês nomes e números de telefone? Óptimo!

      Then, for the pièce-de-résistance, let’s add that user interaction function. Agora que você aprendeu as complexidades do controlador table view, eu acho que você já sabe como esta próxima função funciona.

      override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}

      Novamente, estamos anulando a implementação padrão da função tableView(_:didSelectRowAt:). Esta função é chamada quando um usuário tapa a célula de uma tabela view, e ela pertence ao protocolo UITableViewDelegate. Como as outras funções, é fornecido o caminho de índice da célula que está sob escuta.

      no corpo da função, estamos simplesmente criando uma URL tel:// do número de telefone. Em seguida, dizemos ao aplicativo para abrir essa URL, o que efetivamente diz aos iOS para iniciar uma chamada para este número. Esse código só existe para fins ilustrativos. Note que isso não funciona no simulador de iPhone, e que os números na nossa aplicação são falsos. (Ainda assim, você usaria este código se você está fazendo um aplicativo de contatos reais!)

      pode adicionar o seguinte código à função se quiser verificar se funciona bem.

      print("\(#function) --- Calling: \(contacts)")

      isto irá imprimir uma mensagem de depuração quando tocar na célula da janela da tabela.

      Leitura Adicional

      e é tudo o que há para ele! Foi uma grande viagem, mas agora sabes como funciona um controlador de mesa.