Kelvin Tan
Kelvin Tan

Reputation: 347

TableView containing two array of informations

I have Employee.swift which contains the following code:

import Foundation

struct Employee {
    var name: String
    var favoriteLinks: [String]
    var links: [String]

    init(name: String, favoriteLinks: [String], links: [String]) {
        self.name = name
        self.favoriteLinks = favoriteLinks
        self.links = links
    }
}

And I have ViewController.swift that uses TableView with the following code:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var lists: [Employee] = [People(name: "Employee 1",
                                  favoriteLinks: ["Facebook","Twitter"], 
                                  links: ["www.facebook.com","www.twitter.com"])
                            ]

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
    }

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        cell.textLabel?.text = lists[indexPath.row].name
        return cell
    }


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "showLinks" {
        if let indexPath = self.tableView.indexPathForSelectedRow {
            let destination = segue.destination as? SecondTableViewController
            destination?.talks = lists[indexPath.row].talk
            destination?.links = lists[indexPath.row].link

        }
    }
}

}

And another TableViewController that contains the following code:

import UIKit

class SecondTableViewController: UITableViewController {

var favoriteLinks: [String] = []
var links: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()

}

// MARK: - Table view data source

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

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


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = favoriteLinks[indexPath.row]

    return cell
}
 }

I created a property that contain name of an employee with a lists of his favoriteLinks and links. ViewController contain a tableview that should only contain the name of the employee, if clicked on the employee, you will be redirected to another tableview with a lists of his favoriteLists.

This is the problem. Because the tableview is only showing text and not the link. I would like the text to contain the link as well, in which if clicked upon would direct you to the link connected. For example, if clicked on Facebook, it will show me to www.facebook.com. What would be the best way to go around to achieve this?

I tried creating two separate arrays to contain the information but I have no idea how to call the array that contains the link. Any help would be appreciated. Thank you!

Upvotes: 0

Views: 61

Answers (2)

Vini App
Vini App

Reputation: 7485

You have to add didSelectRowAt in SecondTableViewController like below:

if your lists is like below :

var lists: [Employee] = [Employee(name: "Employee 1",
                                favoriteLinks: ["Facebook","Twitter"],
                                links: ["http://www.facebook.com","http://www.twitter.com"])
]
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    UIApplication.shared.open(URL(string: links[indexPath.row])!, options: [:])
}

if your lists is like below :

var lists: [Employee] = [Employee(name: "Employee 1",
                                favoriteLinks: ["Facebook","Twitter"],
                                links: ["www.facebook.com","www.twitter.com"])
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    var urlStr: String = links[indexPath.row]
    if !urlStr.hasPrefix("http") && !urlStr.hasPrefix("https") {
        urlStr = "http://\(urlStr)"
    }
    UIApplication.shared.open(URL(string: urlStr)!, options: [:])
}

Upvotes: 1

Code Different
Code Different

Reputation: 93161

Better yet, pass the whole Employee record to your second view controller:

class ViewController: UITableViewController {
    // Add the https protocol for the link
    var lists: [Employee] = [
        Employee(name: "Employee 1",
                favoriteLinks: ["Facebook","Twitter"],
                links: ["https://www.facebook.com","https://www.twitter.com"])
    ]

    ...

    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showLinks" {
            if let indexPath = self.tableView.indexPathForSelectedRow {
                let destination = segue.destination as! SecondTableViewController
                // Pass the whole employee record to the second view controller
                destination.employee = lists[indexPath.row]
            }
        }
    }
}

And the second view controller:

class SecondTableViewController: UITableViewController {
    var employee: Employee!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Select the prototype cell in IB and change its style to Subtitle if you want a 2-line label
        // Alternatively you can hide the link altogether, it doesn't affect the outcome
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        // For the first line, we display the name of the link
        cell.textLabel?.text = employee.favoriteLinks[indexPath.row]

        // For the second line, we display the address of the link
        cell.detailTextLabel?.text = employee.links[indexPath.row]
        cell.detailTextLabel?.textColor = .blue
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let href = employee.links[indexPath.row]
        let url = URL(string: href)!

        // Open the URL in whatever app that registered to open it. That could be
        // the Facebook app or the Twitter app instead of Safari. After it has been
        // opened, de-highlight the cell
        UIApplication.shared.open(url, options: [:], completionHandler: { _ in tableView.selectRow(at: nil, animated: false, scrollPosition: .none) })
    }
}

Upvotes: 0

Related Questions