I have an array: var initialArray. That appends every time the screen is tapped. This is done on ViewController 3
I have a table which displays the array in another view controller: ViewController2.
However the issue is: use of unresolved identifier: initialArray.
How can I get ViewController2 to recall variables from ViewController3?
class ViewController2: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
}
//How many rows
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return initialArray
//////use of unresolved identifier: initialArray
}
//What goes in each cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
print(indexPath.row)
cell.textLabel?.text = initialArray[indexPath.row]
//////use of unresolved identifier: initialArray
return cell
}
Related
There are some rows in table view. Each row opens a new view. Now I want to show some sub categories on click of Particular row. each of this sub category opens different view. I am using only 1 section. Any ideas?
Simply do this.
class CategoriesListViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var filterCategories = [CategoryViewModel]()
override func viewDidLoad() {
super.viewDidLoad()
tfSearch.placeholder = LocalizeKey.search.localized
getCategories()
// Do any additional setup after loading the view.
}
extension CategoriesListViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filterCategories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CategoryCellTableView
let category = filterCategories[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let controller : SubCategoriesListViewController = ViewControllerManager.shared.find() {
controller.selectedCategory = self.filterCategories[indexPath.row]
self.pushViewController(controller : controller)
}
}
Sub-Categories will be subclassed from the main categories and override the table view selection methods and do whatever you want to do.
class SubCategoriesListViewController: CategoriesListViewController {
#IBOutlet weak var tableView: UITableView!
var filterCategories = [CategoryViewModel]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let controller = DifferentViewController()
self.pushViewController(controller : controller)
}
I wanted to give a go at swift, and looked at several tutorials. I tried to implement a TableView.
Here is my code :
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var items: [String] = ["lol1", "lol2", "lol3"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
print("You selected cell #\(items[indexPath.row])!")
}
}
MY IBOutlet is connect to the tableview I inserted in the storyboard.
When I run it, I have a TableView, but it's missing contents.
From what I gathered through some (more or less outdated) tutorials, I shouldn't have anything more to do, what am I missing ?
Where are you set dataSource and Deleagte methods of TableView?
use this code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
2 possible reasons:
If the cell is designed as prototype cell you must not register the cell.
dataSource and delegate of the table view must be connected to the controller in Interface Builder or set in code.
I've populated a UITableView with names of restaurants using Google Places API. Now, I am trying to perform a segue to a different view while knowing which cell was clicked with IndexPath. I've tried using the didSelectAtIndexRowPath function but it's not recognizing the tap/click. It should print out the number to the console. What am I doing wrong?
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
var myIndex = 0
#IBOutlet var restuarantsTable: UITableView!
var restaurantsList = [NSDictionary]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
restuarantsTable.dataSource = self
let url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=26.2034071,-98.23001239999996&radius=500&type=restaurant&keyword=tacos&key=AIzaSyBRQZV4SOpcJ-icCe9BuZlI48MzONwH5Dw"
downloadRestaurants(urlString: url) { (array) -> () in
self.restaurantsList = array as! [NSDictionary]
// print(self.restaurantsList.count)
self.restuarantsTable.reloadData()
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return restaurantsList.count
}
#available(iOS 2.0, *)
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let RCell = tableView.dequeueReusableCell(withIdentifier: "RCell", for: indexPath)
// let imgURL = NSURL(string: imgURLArray[indexPath.row])
// let imageView = RCell.viewWithTag(350) as! UIImageView
RCell.textLabel!.text = restaurantsList[indexPath.row]["name"] as? String
// RCell.imageView?.image = restaurantsList[indexPath.row]["photos"] as? UIImage
return RCell
}
private func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
self.performSegue(withIdentifier: "detailSegue", sender: indexPath)
print(restaurantsList[indexPath.row])
}
}
You would have to conform to UITableViewDelegate like you did for UITableViewDataSource, didSelectRowAtIndexPath is a UITableViewDelegate method
Add these lines
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
And in viewDidLoad
restuarantsTable.delegate = self
I think you would have to set delegate in storyboard as well
Go to this tab and ctrl+Drag to the viewcontroller to set it as delegate
Swift 3
Error1:
You have to add UITableViewDelegate protocol for using UITableView delegate methods.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{}
In viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
restuarantsTable.dataSource = self
restuarantsTable.delegate = self
}
Error 2:
The protocol must be confirm with public. You declared as private
change
private func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath){}
to
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
or (below swift 3)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath){}
Modify two things in your code set restuarantsTable.delegate = self and then reload your table on main thread as you are making network call which will handle in background thread. So also modify below code.
DispatchQueue.main.async({
self.restuarantsTable.reloadData()
})
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 6 years ago.
I'm new to Swift. I have two table view controllers, one with static cells and one with dynamic ones. I basically want to let a user select his marital status on the second table view controller and send his choice back to the first table view controller (and display his selection on the cell "Marital Status"). Here is a screenshot of my storyboard:
Storyboard
Current code on second table view controller:
import UIKit
class SecondTableViewController: UITableViewController {
let maritalStatusArray: [String] = ["Single", "Married"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return maritalStatusArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MaritalStatusCell", for: indexPath)
cell.textLabel?.text = maritalStatusArray[indexPath.row]
return cell
}
}
My guess is that I have to add a segue from the dynamic cell of the second view controller back to the first one. Is that right ?
Supposing this is the way to do it, I have afterwards to update the text of the static label to include the choice made by the user. Any ideas ?
There few ways by which you can implement the callback functionality to pass data.
Delegate
Using Block CallBack
Post Notification
But I would suggest to use delegate which is best way, Post Notification is also a way but I do not want to prefer.
You can use custom delegate to do this:
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SecondViewControllerProtocol {
#IBOutlet weak var userInfoTableView: UITableView!
var userInfoArray: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
userInfoArray = ["Marital Status","Canton","Commune","Religion"]
self.userInfoTableView?.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let userInfoCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
userInfoCell.textLabel?.text = userInfoArray[indexPath.row]
if indexPath.row == 0{
userInfoCell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
}
return userInfoCell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0{
let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondViewControllerIdentifier") as! SecondViewController
secondVC.statusDelegate = self
self.navigationController?.present(secondVC, animated: true, completion: nil)
}
}
func changeMaritalStatus(type: String){
let maritalStatusCell = userInfoTableView.cellForRow(at: IndexPath(row:0 , section:0))
maritalStatusCell?.textLabel?.text = String("Marital Status: \(type)")
}
}
SecondViewController.swift:
import UIKit
protocol SecondViewControllerProtocol {
func changeMaritalStatus(type: String)
}
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var maritalStatusTableView: UITableView!
var maritalStatusArray: [String] = []
var statusDelegate : SecondViewControllerProtocol? = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
maritalStatusArray = ["Single","Married","Divorced"]
self.maritalStatusTableView.register(UITableViewCell.self, forCellReuseIdentifier: "maritalStatuscell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let maritalStatusInfoCell = tableView.dequeueReusableCell(withIdentifier: "maritalStatuscell", for: indexPath)
let infoLabel: UILabel = UILabel.init(frame: CGRect(x: 10, y: 5, width: 250, height: 50))
infoLabel.text = maritalStatusArray[indexPath.row]
maritalStatusInfoCell.addSubview(infoLabel)
return maritalStatusInfoCell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
statusDelegate?.changeMaritalStatus(type: maritalStatusArray[indexPath.row])
self.dismiss(animated: true, completion: nil)
}
}
GitHub link:
https://github.com/k-sathireddy/CustomDelegatesSwift
Output:-
I am wondering why is my tableview not populating? I have a tableview inside my view controller and I have tried to follow the guide however, nothing seems to show up on my tableview.
here's my code
#IBOutlet weak var weatherTableView: UITableView!
var items: [String] = ["Sunny", "Cloudy", "Rainy"]
override func viewDidLoad() {
super.viewDidLoad()
self.weatherTableView.register(UITableViewCell.self, forCellReuseIdentifier: "WeatherCell")
// Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.weatherTableView.dequeueReusableCell(withIdentifier: "WeatherCell")! as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
am I missing something here?
Thanks for your help in advance
Make sure you are assigning tableview delegate and datasource throw storyboard or add below line into your viewDidLoad() of your viewcontroller (UITableViewDelegate, UITableViewDataSource)
weatherTableView.delegate = self;
weatherTableView.dataSource = self