UITableView Not Loading Data From Segue - ios

I have a sequence where the user logs in and then they are brought to view showing a UITableView via a segue. I am trying to inject data from the login screen to the table after a successful login.
In the login view...
func transitionToHome() {
print("Hey you logged in!")=
performSegue(withIdentifier: "loginSuccess", sender: self)
self.navigationController!.setNavigationBarHidden(false, animated: false)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! ViewController
vc.models = [(title: "title", note: "Note")]
}
And in the Home Screen view
#IBOutlet var table: UITableView!
#IBOutlet var label: UILabel!
#IBOutlet weak var newNoteButton: UIButton!
var models: [(title: String, note: String)] = []
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
title = "Notes"
}
I have tried to call table.reloadData() in the the viewDidLoad, as well as in viewDidAppear and viewWillAppear. Neither has worked.
I also have printed out models in the viewDidLoad and I saw that the data is being correctly passed to the view controller. But,I cannot get the table to load this data when the view controller is loaded from the segue.

If you models data prints correctly in viewDidLoad() you should be able to configure a tableview cell with the data in the dataSource implementation. See sample extension for the dataSource implementation below. Make sure you provide a reuse identifier to your prototype cell in the storyboard.
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = "This is a cell primary text"
cell.contentConfiguration = content
return cell
}

Related

How can i use uitableview cell for performing segue

I started to learn Swift 2 weeks ago. With some courses and youtube videos, I learn basics of uitableview but I couldn't get how can I use specific table view cell like a button.
What I wanna do?
I am trying to use the sidebar menu(https://github.com/yannickl/FlowingMenu) for my project, everything is cool and working okay instead of using cells.
In every basic tutorial people showing how to use segue with uitableview but they only use 2 pages and independent from cell value, no matter what text in your cell it calls segue for the second controller.
I want to use the sidebar menu with cells and if my cell value is "main menu" I want to perform "toMainMenu" segue.
I only know using cells with arrays don't know is there any other way for work with cells, and my main goal is cell-specific segue.
I watched a lot of tutorials but can't find anything useful for me.
import UIKit
import FlowingMenu
class SideBarMenu: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var surnameLabel: UILabel!
#IBOutlet weak var topBar: UINavigationBar!
#IBOutlet weak var backButtonItem: UIBarButtonItem!
#IBOutlet weak var userTableView: UITableView!
#IBOutlet weak var profilePic: UIImageView!
let CellName = "Menu"
let mainColor = UIColor(hex: 0xC4ABAA)
var sections = ["Main Menu", "Settings", "Profile"]
override func viewDidLoad() {
super.viewDidLoad()
userTableView.delegate = self
userTableView.dataSource = self
nameLabel.text = Helper.name
surnameLabel.text = Helper.surname
topBar.tintColor = .black
topBar.barTintColor = mainColor
topBar.titleTextAttributes = [
NSAttributedString.Key.font: UIFont(name: "HelveticaNeue-Light", size: 22)!,
NSAttributedString.Key.foregroundColor: UIColor.black
]
userTableView.backgroundColor = mainColor
view.backgroundColor = mainColor
}
// MARK: - Managing the Status Bar
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
// MARK: - UITableView DataSource Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = sections[indexPath.row]
cell.contentView.backgroundColor = mainColor
return cell
}
// MARK: - UITableView Delegate Methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Select row at")
}
#IBAction func profileButton(_ sender: Any) {
performSegue(withIdentifier: "toProfile", sender: nil)
}
}
I want to perform "toSettings" segue when "Settings" cell clicked.
Implement the UITableViewDelegate protocol method tableView(_:didSelectRowAt:) as below
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch sections[indexPath.row] {
case "Main Menu":
performSegue(with: "toMainMenu", sender: nil)
case "Settings":
performSegue(with: "toSettings", sender: nil)
case "Profile":
performSegue(with: "toProfile", sender: nil)
}
}
If you need to configure or pass some data to the destination controller, you can override the controller's prepare(for:sender:) method to get a reference, for example:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toMainMenu" {
let dvc = segue.destination as! MenuViewController
// now you have a reference
}
}
If I understand, your menu is a tableView, so you need to segue to the view you wanna open in the table didSelectAt
You can use override prepare for segue. so when you link your views with a segue you set an identifier for each one and can call whatever you need from there.

add a row to the tableView from another viewController

what I did so far:
I create a tableView controller with empty rows, and a popup window on another ViewController, the purpose of the popup is to add two data(name - link) to the tableView on one ROW (passing Textfields).
what I want :
when I add a new raw (name - link) click save , I want the data to be stored , when I add other data, create another row .
my problem: when I tray to add more raws, it's always wright over the old one, so no matter how much data I input, the result always be 1 row!
popup VC
#IBOutlet weak var nameP: UITextField!
#IBOutlet weak var linkP: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let SEC: TEstVC = segue.destination as! TEstVC
SEC.add(name: nameP.text!, link: linkP.text!)
}
HomeScreen VC
class TEstVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var names = [String]()
var links = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 100.0
tableView.dataSource = self
tableView.delegate = self
}
func add(name: String, link: String) {
names.append(name)
links.append(link)
}
override func viewWillAppear(_ animated: Bool) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count //or links.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.cell4Name.text = names[indexPath.row]
cell.cell4Link.text = links[indexPath.row]
return cell
}
Move your array declaration to global and call reloadData in your tableView like this:
//Popup
#IBOutlet weak var nameP: UITextField!
#IBOutlet weak var linkP: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let SEC: TEstVC = segue.destination as! TEstVC
SEC.add(name: nameP.text!, link: linkP.text!)
self.tableView.reloadData()
}
Your VC
var names = [String]()
var links = [String]()
class TEstVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 100.0
tableView.dataSource = self
tableView.delegate = self
}
func add(name: String, link: String) {
names.append(name)
links.append(link)
}
override func viewWillAppear(_ animated: Bool) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count //or links.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.cell4Name.text = names[indexPath.row]
cell.cell4Link.text = links[indexPath.row]
return cell
}
Simple, after you add a new item to the datasource (names) you need to reload the tableview.
self.tableView.reloadData()
Well, it looks like you're going to a completely new instance of TestVC every single time. So, it's not overwriting the old line. It's putting a new line in a new instance of TestVC. I infer this because you're calling add(name:link:) in prepareForSegue, which gets called by the storyboard when a new viewController is being put on screen with a segue.
Also, your add(name:link:) method should call tableView.reloadData() if you want it to update the screen.

Passing data from view controller to table view controller in ios swift 2

I am using swift 2 beaucse my lappy does not suppoeted swift 3 beacuse of some issue.
I want to pass data from view controller to table view controller ..
but i got some error and here is my code
I want to pass value form view controller .I am using label . whatever i will write in label it will disply in table view controller. so it will REALTIME value !
I am using two view controller and one table view controller ...i have error in table view controller.
I have some errors
1) cell1.textLabel!.text = tblLable.text! // error UItableview has no memeber in 'text'
view controller
#IBOutlet var labelText: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
let DestViewController:PassDataView = segue.destinationViewController as! PassDataView
DestViewController.passdata = labelText.text!
//print(DestViewController.passdata)
}
passdataview
#IBOutlet var Label: UILabel!
var passdata=String()
override func viewDidLoad()
{
Label.text=passdata
}
}
tableviewcontroller
override func viewDidLoad() {
super.viewDidLoad()
//myTableView.delegate = self;
// myTableView.dataSource = self;
}
#IBOutlet var tblLable: UITableView!
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
let DestViewController:PassDataView = segue.destinationViewController as! PassDataView
DestViewController.passdata = tblLable.text!// error UItableview has no memeber in 'text'
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell1 = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath)
cell1.textLabel!.text = tblLable.text! // error UItableview has no memeber in 'text'
return cell1
}
You have to declare String variable in your 3rd View Controller (Table View Controller) like
var myString: String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
You can assign value to myString variable from your first view controller like
let DestViewController:tableviewcontroller = segue.destinationViewController as! tableviewcontroller
DestViewController.myString = labelText.text!
And your your tableview view method will be like
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell1 = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath)
cell1.textLabel!.text = myString
return cell1
}
The Above is the solution, below i am explaining what was the problem
There is no such text method for UITableview, hence you were getting error at
DestViewController.passdata = tblLable.text! //In first View Controller
cell1.textLabel!.text = tblLable.text! //In second View controller

How to change the label of a different view controller when selecting data from a tableviewcontrollerin Swift 3 / xCode 8?

I have a view controller which is used as a table view. From the table view I wish to select an item from the rows available and once selected I wish for that chosen thing to be the name of a label in a second view controller.
So
tableViewController - select an item from the list in the table
secondViewcontroller - label name is what is selected in the tableViewController
I have looked around and there is talk of using NSNotification but I can't seem to get it to work, in addition to using prepareForSegue.
My relevant code for the tableViewContrller is this:
//MARK Table View
//number of sections the table will have
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
//number of rows each section of the table will have
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return peripheralArray.count
}
//the way the data will be displayed in each row for the sections
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let BluetoothNaming = peripheralArray[indexPath.row].peripheral.name
cell.textLabel?.text = BluetoothNaming
return cell
}
//what happens when we select an item from the bluetooth list
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
stopScanning()
peripheral = peripheralArray[(indexPath as NSIndexPath).row].peripheral
print ("connecting to peripheral called \(peripheral)")
//store the name of the connected peripeheral
let connectedPeripheral = peripheral
manager?.connect(connectedPeripheral!, options: nil)
performSegue(withIdentifier: "segueBackwards", sender: nil)
}
My secondViewController does not have much on its just the label:
import UIKit
class HomepageViewController: UIViewController {
#IBOutlet var ConnectionLabel: UILabel!
func changeBlueoothLabel() {
self.ConnectionLabel.text = "aaaa"
}
}
What do I need to do so that when I select a row in the table that the label in the secondViewController changes its label to reflect it.
Furthermore, if I wanted to change it so that I have another label on the secondViewController and I wanted to change it from disconnected to connected, would there be much more work involved?
Many thanks
to pass data add a string variable in the HomepageViewController and implement prepareForSegue method to pass selected name from tableViewController to HomepageViewController
in HomepageViewController
var selectedName: String?
in tableViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showHomePage" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let peripheral = peripheralArray[indexPath.row].peripheral.name
let homeController = segue.destination as! HomepageViewController
homeController.selectedName = peripheral
}
}
in HomepageViewController
import UIKit
class HomepageViewController: UIViewController {
#IBOutlet var ConnectionLabel: UILabel!
var selectedName: String?
override func viewDidLoad() {
super.viewDidLoad()
// Used the text from the First View Controller to set the label
if let name = selectedName {
ConnectionLabel.text = name
}
}
}

What is the missing command to carry the cell title from UITableView to new ViewController via this segue?

I have ViewController that contains a UITableView. Data is loaded into that table via the following code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UsernameSentDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var receiveUsername: UILabel!
#IBOutlet weak var userEmailText: UILabel!
var userEmail: String?
var communities = [String]() { didSet { communitiesTableView.reloadData()
}
}
var flag = false
#IBOutlet weak var communitiesTableView: UITableView!
#IBAction func unwindToHome(_ segue: UIStoryboardSegue) {
}
//recieves email address from delegate from LoginViewController
func userLoggedIn(data: String) {
userEmailText.text = data
}
override func viewDidLoad() {
super.viewDidLoad()
self.communitiesTableView.delegate = self
self.communitiesTableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.communities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let title = self.communities[indexPath.row]
let cell = UITableViewCell()
cell.textLabel?.text = title
return cell
}
I then set up 1 prototype cell within the UITableView so I could create a segue to my second view controller, ShowCommunitiesViewController and named this segue, "showCommunitySegue"
In ShowCommunitiesViewController I have a label set up and ready to use as the title of the cell name carried across, named communityName.
In ViewController I have set up the following function to deal with the segue, including the destination variable for the cell title that has been selected.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showCommunitySegue", sender: self)
showCommunityController.communityName = //what do I put here?
}
What do I need to put on that last line so showCommunityController.communityName displays the cell title?
Just declare selectedCellTitle as String in your viewController where your cells are.
var selectedCellTitle: String?
This will be the global variable keeping track of the selected cell's title.
Add the following in didSelectRowAt:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Set your global variable to the title
self.selectedCellTitle = self.communities[indexPath.row]
// Trigger your segue
performSegue(withIdentifier: "showCommunitySegue", sender: self)
}
Override prepareforsegue method the following way:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showCommunitySegue" {
// Check if the segue's destination viewcontroller is your viewcontroller
if let showCommunityController = segue.destination as? ShowCommunityViewController {
// Assign the selected title to communityName
showCommunityController.communityName = self.selectedCellTitle
}
}
}

Resources