Uable to trigger the action on pressing table cell in swift - swift

I am unable to trigger an action as i click on the table cell. The background of the pressed cell is just gray after pressing the cell. But the action is not performing. Please help.
import UIKit
class ViewController: UIViewController, UITableViewDataSource , UITableViewDelegate
{
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
var loki_images:[UIImage] = [UIImage(named: "images.png")!,
UIImage(named: "images (1).png")!,
UIImage(named: "images (2).png")!]
var persons = [ "Lokesh Ahuja" , "Raghav Mittal" , "Tul-Tul" ]
var identities = ["A","B","C"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return persons.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
let Name = persons[indexPath.item]
cell!.textLabel!.text = Name
let image = loki_images[indexPath.row]
cell!.imageView?.image = image
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let id = identities[indexPath.item]
let viewController = storyboard?.instantiateViewControllerWithIdentifier(id)
self.navigationController?.pushViewController(viewController!, animated: true)
}
}

Are your UIViewController is in navigation controller
if not then you should replace
self.navigationController?.pushViewController(viewController!, animated: true)
with
self.present(viewController, animated: true, completion: nil)

Have your proparly connected Table's UITableViewDelegate with View Controller in Storyboard. Check it. If you not connect it than didselect will not called.

Related

tableview to tableview protocol delegates

I am trying to finish this app that is a form. once filled out a button later will be pushed for print. The first controller has a tableview that has page 1 page 2 page 3. page 1 opens and you fill in all info. when hit save it should take you back to first controller. then when you push print opens the tableview and loads all info.
I am struggling to use structs correctly. also struggling on the save button to the delegate to the print controller page.
my page controller code
class PagesController: UIViewController, UITableViewDelegate {
var pages = ["Page 1","Page 2","Page 3"]
#IBOutlet weak var pagesTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
pagesTableView.delegate = self
pagesTableView.dataSource = self
}
#IBAction func printBtnPressed(_ sender: Any) {
} }
extension PagesController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PagesCell")
cell?.textLabel?.text = pages[indexPath.row]
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
performSegue(withIdentifier: "ChildInfoSegue", sender: self)
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 90.0
}
}
Heres my form controller
protocol ChildDelegate {
func saveInfoBlock(form: ChildInfo)
}
class ChildInfoTableViewController: UITableViewController {
var formDelegate: ChildDelegate!
var firstNameText: UITextField = UITextField()
var lastNameText: UITextField = UITextField()
var middleNameText: UITextField = UITextField()
//MARK: From ChildInfo.swift STRUCT
var childInfo = [ChildInfo]()
var basicChildInfo = ["Child's First Name","Child's Middle Name","Child's Last Name"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in 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 basicChildInfo.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChildInfoCell") as! ChildInfoTableViewCell
cell.formLabel.text = basicChildInfo[indexPath.row]
return cell
}
//MARK: Segue to printController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let path = self.tableView.indexPathForSelectedRow!
let destViewController = segue.destination as! PrintPageTableViewController
}
//MARK: Cancel Button Pressed
#IBAction func cancelBtnPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func saveBtnPressed(_ sender: Any) {
let firstname = firstNameText.text ?? ""
let middlename = middleNameText.text ?? ""
let lastname = lastNameText.text ?? ""
let formData = ChildInfo(cFirstName: firstname, cMiddleName: middlename, cLastName: lastname)
self.navigationController?.popViewController(animated: true)
formDelegate.saveInfoBlock(form: formData)
saveInfoBLock()
}
func saveInfoBLock() {
print("Saving Info")
dismiss(animated: true, completion: nil)
}
}
Heres my struct that I don't properly use
struct ChildInfo {
var childFirstName: String?
var childMiddleName: String?
var childLastName: String?
var childsMadeUpName: String = ""
init(cFirstName: String, cMiddleName: String, cLastName: String) {
self.childFirstName = cFirstName
self.childMiddleName = cMiddleName
self.childLastName = cLastName
}
}
and lastly my tableviewcell
class ChildInfoTableViewCell: UITableViewCell {
#IBOutlet weak var formText: UITextField!
#IBOutlet weak var formLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Once the delegate protocol gets passed. What would a put in the printtableviewcontroller to make the data show? I had someone help me on here, but It was all programmatically and I'm no that advanced yet.
There are several things you can do:
Use delegation. I am assuming this is what you want to achieve here.
Pass your data through Segues. ( Recommended )
To use delegation, you have to have a clear concept of how delegation works.
Here is a link to an explanation I gave someone on another site. It breaks it down, I think this may help you a bit.
https://teamtreehouse.com/community/totally-confused-with-the-example-used
For now, I think the solution to your problem is to use Segues.
When you tap on the button to take you to the ChildInfoTableViewController where you fill the information is where you want to create your "ChildInfo" object. Then when you press save, you trigger the segue and pass the "ChildInfo" object to the "PagesController".
Then from there, that same object should be pass through the segue into the print view.

UITableview doesn't show the cell I made as nib File in swift

Hello I'm in trouble with making UITableview. I made cell as nib file and want to display the cell in the UITableView. But nib file doesn't show in the UItableview when I start the app. I don't know how to figure this out. the source is below
import UIKit
class DownLoadPlayViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet var tableview: UITableView!
#IBOutlet var totalNumSizeInfo:UILabel!
let cellID:String = "DownLoadPlayViewControllerCell"
var downloadedContents: [Dictionary<String,String>] = []
var showContents: Dictionary<String,String> = [:]
override func viewDidLoad() {
super.viewDidLoad()
self.tableview.delegate = self
self.tableview.dataSource = self
self.tableview.registerClass(DownLoadPlayViewControllerCell.classForCoder(), forCellReuseIdentifier: "DownLoadPlayViewControllerCell")
// self.tableview.registerClass(DownLoadPlayViewControllerCell.self, forCellReuseIdentifier: "DownLoadPlayViewControllerCell")
// self.tableview.registerNib(UINib(nibName: "DownLoadPlayViewControllerCell", bundle: nil), forCellReuseIdentifier: "DownLoadPlayViewControllerCell")
downloadedContents = getDownloadInformation()!;
totalNumSizeInfo.text = "초기화 상태"
// let contentInfo : Dictionary<String,String> = self.downloadedContents[0]
// print(contentInfo["contentTitle"])
// print(contentInfo["viewDate"])
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*Podlist에 있는 다운로드 파일정보를 가져온다. */
func getDownloadInformation() -> [Dictionary<String,String>]?{
var returnValue : [Dictionary<String,String>]? =
NSUserDefaults.standardUserDefaults().objectForKey("downloadedContents") as? [Dictionary<String,String>]
if((returnValue?.isEmpty) == true){
returnValue = nil
}
return returnValue
}
// func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// return 1
// }
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return downloadedContents.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
// let cell = tableView.dequeueReusableCellWithIdentifier("DownLoadPlayViewControllerCell", forIndexPath: indexPath) as! DownLoadPlayViewControllerCell
let cell = tableView.dequeueReusableCellWithIdentifier("DownLoadPlayViewControllerCell") as! DownLoadPlayViewControllerCell
let contentInfo : Dictionary<String,String> = self.downloadedContents[indexPath.row]
cell.titleLabel?.text = contentInfo["contentTitle"]
cell.dateLabel?.text = contentInfo["viewDate"]
return cell;
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let contentInfo : Dictionary<String,String> = self.downloadedContents[indexPath.row]
print(contentInfo["downLoadURL"])
}
//MARK: ButtonClickArea
#IBAction func closeButtonClick(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
You need reloadData for your tableview after run the command downloadedContents = getDownloadInformation()!. Just run tableview.reloadData() like that:
downloadedContents = getDownloadInformation()!;
tableview.reloadData() //---------> add new like here
totalNumSizeInfo.text = "초기화 상태"
Here is how to use a custom created cell.
Note: I am not using StoryBoard and I have created the cell in a nib.
CustoMCell Class Code:
import UIKit
class ActivityTableViewCell: UITableViewCell {
// MARK: - Constants & variable
// your outlets if any
// MARK: - UITableViewCell methods
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
// MARK: - helper methods
class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> ActivityTableViewCell {
let kActivityTableViewCellIdentifier = "kActivityTableViewCellIdentifier"
tableView.registerNib(UINib(nibName: "ActivityTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: kActivityTableViewCellIdentifier)
let cell = tableView.dequeueReusableCellWithIdentifier(kActivityTableViewCellIdentifier, forIndexPath: indexPath) as! ActivityTableViewCell
return cell
}
}
And this is how I use it in my TableView
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = ActivityTableViewCell.cellForTableView(tableView, atIndexPath: indexPath)
// access your cell properties here
return cell
}
I solve the problem by modifying the tablecellController like this
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.alpha = 0
UIView.animateWithDuration(0.2, delay: 0, options: .CurveEaseIn, animations: {
self.alpha = 1
}, completion: { finished in
})
}

How to make a segue by a tableViewDelegate

I'd like to create a segue from a tableViewDelegate cell to an other view. This is my code:
import UIKit
class CoriViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
#IBOutlet var tableView: UITableView!
var elencoCori : SquadraModel! //This var contains label and array
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
InterfaceManager.sharedInstance.putBlurBackgroundToTableView(self.view, tableView: self.tableView)
self.tableView.tableFooterView = UIView(frame:CGRectZero)
self.tableView.backgroundColor = UIColor.clearColor()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.elencoCori.cori.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell : UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
let coro = elencoCori.cori[indexPath.row]
cell.textLabel?.text = coro.marker
cell.backgroundColor = UIColor.clearColor()
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("toDettaglioController", sender: self)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
Now the problem: how I could set a prepareForSegue that send to the secondView? In other circumstances I would have solved the problem like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "toDettaglioController"
{
if let indexPath = tableView.indexPathForSelectedRow()
{
let controller = segue.destinationViewController as! Dettaglio controller
controller.coro = elencoCori.cori[indexPath.row]
}
}
}
but I know the this doesn't work and I have to use a delegate method. So can everyone help me with a step-by-step guide?
On your didSelectRowAtIndexPath method call performSegueWithIdentifier and pass the indexPath as your sender.
Then in prepareForSegue you can do if let indexPath = sender as NSIndexPath and setup your controller.
Suppose you have One UITableViewController-T and Two UIViewControllers-A and B.
Now suppose you want to go from T to A when cell 0 is clicked, and go from T to B when cell 1 is clicked.
Step 1 : Connect segue from T to A and name that segue "segueToA"
Step 2 : Connect segue from T to B and name that segue "segueToB"
Step 3 : Got to didSelectRowAtIndexPath in T and put if-else
if(indexPath.row == 0){
self.performSegueWithIdentifier("segueToA", sender: nil)
}else{
self. performSegueWithIdentifier("segueToB", sender: nil)
}
That's it.
Update: Here is a Sample Project.

Swift - 2 tableviews and detailviewcontroller

have problem with 2 tableviews on 2 viewcontrollers and detailviewcontroller, everything is almost working ok, 2 tableviews working like a charm, but problem is in secondviewcontroller where i put array of images to segue to detailVC after each meal/food is clicked, i got same 3 images for mexican food, spanish food, italian, croatian and french. Images(15) does to correspond to 15 meals. Did i go wrong with putting array of images in second view controller? Thank you
ViewController
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
let textForFirstTableView = ["Italian food", "Mexican food", "Croatian food", "Spanish food", "French food"]
let namesOfFood = [["Bolognese", "Milagnese","Pizza"],
["Tortilla", "Chimichanga", "Paella"],
["Burek od mesa","Grah", "Janjetina"],
["Tapas", "Churros", "Flan"],
["Buche de Noel", "Cherry Cake", "Onion Soup"]]
var ObjectNamesOfFood = [String]()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.delegate = self
self.tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return textForFirstTableView.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = textForFirstTableView[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.ObjectNamesOfFood = self.namesOfFood[indexPath.row]
self.performSegueWithIdentifier("Segue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let driver = segue.destinationViewController as! DrugiViewController
var whatToPass = self.ObjectNamesOfFood
driver.arrayToPass = whatToPass
}
}
SecondViewController
import UIKit
class DrugiViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var arrayToPass:[String] = [String]()
var picturesForEachMeal = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]
var objectpicturesForEachMeal:String!
#IBOutlet weak var tableView2: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView2.delegate = self
self.tableView2.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayToPass.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell2") as! UITableViewCell
cell.textLabel?.text = arrayToPass[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.objectpicturesForEachMeal = self.picturesForEachMeal[indexPath.row]
self.performSegueWithIdentifier("toDetailViewController", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let driver = segue.destinationViewController as! DetailViewController
driver.picturesToRetrieve = objectpicturesForEachMeal
}
}
DetailViewController (displaying 15 images for 15 meals)
import UIKit
class DetailViewController: UIViewController {
#IBOutlet weak var backgroundImage: UIImageView!
#IBOutlet weak var slika: UIImageView!
var picturesToRetrieve:String!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var connection = self.picturesToRetrieve
self.slika.image = UIImage(named: connection)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In View Controller store the selected index and pass it to DrugiViewController
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.ObjectNamesOfFood = self.namesOfFood[indexPath.row]
self.selectedKitchen = indexPath.row
self.performSegueWithIdentifier("Segue", sender: self)
}
In DrugiViewController calculate each food image index
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var totalIndex = (indexPath.row) + (selectedKitchen * 3)
self.objectpicturesForEachMeal = self.picturesForEachMeal[totalIndex]
self.performSegueWithIdentifier("toDetailViewController", sender: self)
}
that's it
I must say this is not the best approach if you was starting an app from begining you should in your case use an dictionary of array that contain a key country and as result an array of dictionary dish and photo in the first view controller.
In the second view controller you should have an array of dictionary that contain the dish and photo.
In the third view just a simple dictionary that contain a dictionary with dish and photo.
But how you almost finish the easier solution for you is to pass the value from the first table to the second, so lets say if the user selected row 2 you pass and keep that values.
Now in the second table if the user selected row 3 you multiply the number of the row the user selected (3) by the number of the first row select in table view one (2) and you know you have to display the picture number 6 in your final array.
I hope this helps you, I am sure now that you know the idea you will be able to finish your project. Best of luck!
First view controller:
var rowSelected:Int?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.ObjectNamesOfFood = self.namesOfFood[indexPath.row]
self.rowSelected = indexPath.row
self.performSegueWithIdentifier("Segue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let driver = segue.destinationViewController as! DrugiViewController
var whatToPass = self.ObjectNamesOfFood
driver.arrayToPass = whatToPass
driver.rowSelected = rowSelected
}
Second view controller:
var rowSelected:Int?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.objectpicturesForEachMeal = self.picturesForEachMeal[indexPath.row * self.rowSelected]
self.performSegueWithIdentifier("toDetailViewController", sender: self)
}
This is the basic idea, sorry I couldn't test it as I am in a Windows computer now, but should just work

How to use navigationController to show up a WebView when I choose one cell from the tableView?

When we choose one cell from the tableView, we use the didSelectRowAtIndexPath method to implement the specific operation.
Then how to jump to another view like webView via the navigationController?
I want to use the prepareForSegue to handle this issue like below, and I just know how to pass data from one viewController to another viewController.
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!){
var channelC:ChannelController=segue.destinationViewController as ChannelController
channelC.delegate = self
//将channelData传递给ChannelController中去。
channelC.channelData=self.channelData
}
I don't know how to code in the didSelectRowAtIndexPath method when I want to show up another view like WebView?
I just use the storyboard to handle viewController switch thing.
Thanks
Here I create a simple example for you :
import UIKit
class ViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
var arr: [String] = ["google", "yahoo", "Swift"]
var index : Int = Int()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arr.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var identifier : NSString = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? UITableViewCell
if !(cell != nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: identifier)
}
cell?.textLabel.text = self.arr[indexPath.row]
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
//store your clicked row into index
index = indexPath.row
// get to the next screen
self.performSegueWithIdentifier("goNext", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "goNext") {
var webViewController = segue.destinationViewController as googleViewController
//switch case for row which you have clicked
switch index{
case 0:
webViewController.url = "https://www.google.co.in/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8"
case 1:
webViewController.url = "https://in.yahoo.com/"
case 2:
webViewController.url = "https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_456"
default:
println("nothing")
}
}
}
}
here is code for your googleViewController.swift
#IBOutlet weak var webView: UIWebView!
var url : String = String()
override func viewDidLoad() {
super.viewDidLoad()
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!)
webView.loadRequest(request)
}
May be this will help you.