I am new to swift and am trying to create an app with a table view which can use the view from another UIView controller.
Is it doable?
If so please help me with it, I have attached my code for the main controller below. Please let me know if anything is wrong?
Thank you so much.
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var numbers:[String] = []
let vc = bgViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.backgroundView = vc.view
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(numbers.count == 0){
tableView.backgroundView?.hidden = false
println("1")
}
else{
tableView.backgroundView?.hidden = true
}
return numbers.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
return cell
}
}
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var numbers:[String] = []
var vc: bgViewController!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
vc = self.storyboard.instantiateViewControllerWithIdentifier("bgViewController") as! bgViewController
tableView.backgroundView = vc.view
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(numbers.count == 0){
tableView.backgroundView?.hidden = false
println("1")
}
else{
tableView.backgroundView?.hidden = true
}
return numbers.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
return cell
}
}
Provide storyboard identifier as bgViewController in attribure inspector.
Related
I have set up tableview many times but don't why is not it showing anything. I have added a tableview on my storyboard file, added reference on ViewController file and set datasource and delegate on storyboard. on viewDidLoad registered the cell and finally added reusableIdentifier on TableViewCell. Here is my code with details configuration :
import UIKit
struct ViewControllerConstants {
static let kCellIdentifier = "TableViewCell"
static let kNibName = "TableViewCell"
}
class ViewController: UIViewController {
var cellImageNames : [String] = ["image1","image2","image3","image4","image5","image6"]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.register(UINib.init(nibName: ViewControllerConstants.kNibName, bundle: nil), forCellReuseIdentifier: ViewControllerConstants.kCellIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
self.tableView.reloadData()
}
}
extension ViewController : UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellImageNames.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: ViewControllerConstants.kCellIdentifier, for: indexPath) as? TableViewCell {
cell.contentImageView.image = UIImage.init(named: cellImageNames[indexPath.row])
return cell
}
return UITableViewCell.init()
}
}
extension ViewController : UITableViewDelegate {
}
Try to remove identifiers for cells in storyboard.
Problem: Cell height was not defined on code. So it was creating cell with 0 height value .
Solution: Need to specify height of each row as below code:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
Everything works, except when I click on a row.. nothing happens it should output You selected cell number:
class JokesController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var jokes_list: UITableView!
var CountCells = 0
var CellsData = [[String: Any]]()
override func viewDidLoad() {
super.viewDidLoad();
Alamofire.request("http://localhost:8080/jokes.php").responseJSON{ response in
if let JSON = response.result.value as? [[String: Any]] {
self.CellsData = JSON
self.CountCells = JSON.count
self.jokes_list.reloadData()
}else{
debugPrint("failed")
}
}
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return CellsData.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell.textLabel?.text = CellsData[indexPath.row]["title"] as! String?
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
debugPrint("You selected cell number: \(indexPath.row)!")
}
}
First, you need to inherit from UITableViewDelegate (class ... : UIViewController, UITableViewDelegate.. ).
Then, you need to assign
self.jokes_list.delegate = self
self.jokes_list.dataSource = self
tentatively in your viewDidLoad.
Edit: As #zsteed mentioned.
I have a simple project, with UITableView added as subview of the current view, and external tableviewcontroller class that make a delegate and datasource.
The problem is that all work correctly excepted delegate didSelectedRowAtIndexPath, when I click in a single row, all tableview become white, here is the code:
MAIN CLASS:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let cont:Tbcontroller = Tbcontroller()
let tableViewInner = UITableView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width-(self.view.frame.width/6), height: 180))
tableViewInner.scrollEnabled = false
tableViewInner.separatorStyle = .None
tableViewInner.allowsSelection = true
tableViewInner.userInteractionEnabled = true
cont.type = 1
cont.setCurrentTableView(tableViewInner)
self.view.insertSubview(tableViewInner, atIndex: self.view.subviews.count+1)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
EXTERNAL CLASS DELEGATE DATASOURCE:
import UIKit
class Tbcontroller: UITableViewController {
var type:Int = 1
override func viewDidLoad() {
super.viewDidLoad()
}
func getCell() -> UITableViewCell{
let presentCell: UITableViewCell = UITableViewCell()
return presentCell
}
func setCurrentTableView(table:UITableView){
self.tableView = table
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 4
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = getCell()
cell.textLabel?.text = "ciao"
cell.textLabel?.font = UIFont.systemFontOfSize(13)
return cell
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("clicked")
}
}
When I click, I do not see the output "clicked"
Your main problem is that TbController() get deallocated. dataSource and delegate properties on UITableView are weak. Therefor, because you only assign TbController to a local variable and to the weak properties, it will get deallocated.
Also, the UITableViewController already creates a TableView for you. It is not good practice to "recreate" it. I would rather make use of the TableView in the UITableViewController and add the UITableViewController's view as a subview to your UIViewController's view.
To fix, you need an instance variable for TbController.
Sample code with ivar for TbController and making use of Tbcontroller's UITableView.
import UIKit
class ViewController: UIViewController {
var cont: Tbcontroller = Tbcontroller()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
cont.type = 1
self.view.addSubview(cont.view)
}
}
import UIKit
class Tbcontroller: UITableViewController {
var type:Int = 1
override func viewDidLoad() {
super.viewDidLoad()
tableView.scrollEnabled = false
tableView.separatorStyle = .None
tableView.allowsSelection = true
tableView.userInteractionEnabled = true
self.tableView.delegate = self
self.tableView.dataSource = self
}
func getCell() -> UITableViewCell{
let presentCell: UITableViewCell = UITableViewCell()
return presentCell
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 4
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = getCell()
cell.textLabel?.text = "ciao"
cell.textLabel?.font = UIFont.systemFontOfSize(13)
return cell
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("clicked")
}
}
thanks to Carien, it works fine, i changed uitableviewcontroller with:
: NSObject, UITableViewDataSource, UITableViewDelegate
I have an UITableViewController that has 2 cells and when I put a photo in it, it comes out to be the same size. The coding I put in the ViewController.swift is
import UIKit
class TableViewController: UITableViewController {
var imageArray = ["1.png","2.png"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!
let imageView = cell.viewWithTag(2) as! UIImageView
imageView.image = UIImage(named: imageArray[indexPath.row])
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return imageArray.count
}
}
I'm not sure of what you are looking for? If what you want is two cells with differents height, you should try to override
override func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
}
in your delegate.
I'm trying to create a table as the main screen of my app and I'm having some issues. I set up the main.storyboard correctly, but there's an override func I have that "doesn't override a superclass". The error is on the nuberOfRowsInSection override func line. Here's my code:
import UIKit
class ViewController: UITableViewController {
var candies = [Candy]()
#IBOutlet weak var editButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup
// after loading the view.
self.candies = [Candy(name: "Jolly Rancher"),Candy(name: "Snickers"),Candy(name: "Twix"),Candy(name: "Butterfinger"),Candy(name: "Milky Way")]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, nuberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var candy : Candy
candy = candies [indexPath.row]
cell.textLabel?.text = candy.name
}
#IBAction func editButtonPressed(sender: UIButton) {
editButton.setTitle("Save", forState: UIControlState.Normal)
}
}
Just a guess:
// this should read "numberOfRowsInSection": ~~v
override func tableView(tableView: UITableView, nuberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
As far as I know, UITableViewController does not have a method with a parameter nuberOfRowsInSection, but it does have one with a parameter numberOfRowsInSection.
When dealing with something that isn't working, please start by checking your code for spelling mistakes.
You have a typing mistake. You call the method nuberOfRowsInSection. There is a 'n' missing. The method should be called numberOfRowsInSection.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
Also you have en error in your cellForRowAtIndexPath method. You have to return the cell:
return cell