student list on button click in swift - ios

In my main.storyboard there has "all student" button. I need to open student list when "all student" button will be clicked.
Students are already saved in realm db. So far I've done below:-
Have dragged view controller from object library and have placed in empty space.
Have also dragged table view and table view cell inside view controller.
Created a modal segue from "all student" button to this view controller.
Have given cell identifier to "Cell" and segue identifier to "rList"
In vieController, I've made the following changes:-
Class vieController: UIvieController, UITextfieldDelegate
to below:
Class vieController: UIvieController, UITextfieldDelegate, UITableViewDelegate, UITableViewDatasource.
but getting below error in viewDidLoad:
fatal error: unexpectedlyfound nil while unwrapping an optional value
on below line:
table1.dataSource = self
Not getting how I'll achieve this student list. Any help would be appreciated.

Delete the line table1.dataSource = self
Then go to the Connections Inspectors of tableView from storyboard
after that drag the dataSource to your viewController
also make sure that your tableView outlet is connected properly.
I hope this help you

First, you should check to make sure that you have a proper table view outlet in your view controller. I show in my screenshot how the table view outlet is created.
You can then use
self.tableView.dataSource = self
in your viewDidLoad.
As far as getting the data to show, you can put your data into an array property in your view controller.
If the data is being loaded from the network, then the table view should be reloaded using tableView.reloadData() after the data has loaded.
The other pieces that you seem to be missing are the required data source methods for a UITableViewDataSource.
There are two functions that are required and they belong in your view controller.
I’ve provided minimal outlines below to get you started.
func tableView(tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// The cell identifier is set in your storyboard.
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
// Do stuff like set values on labels in the cell.
cell.label.text = “text to display”
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
// Return the number of cells to be displayed.
return 10
}

Related

Table View Delegate method (didSelectRowAt) not called when row pressed

I am trying to perform a segue when the user presses a certain cell/ row on a table View. I have implemented the delegate protocol
extension myVC : UITableViewDelegate
Here is my didSelectRow function
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "searchToOtherUser", sender: self)
}
There is also some extra stuff done in the previous function but when I put a breakpoint within the function, I can see that the app never goes into this function.
I have seen some of the answers previously mentioned on this topic (no user gesture is being used, and user interaction with the table view is enabled).
Does anyone have an idea on how I could fix this?
Thank you so much
Anthony
If the content is loading and the selection is enabled, then things to check are:
1) set delegate programmatically in swift
2) (optional) set the tableview delegate to File's Owner in case you added a tableview to your UIViewController in Storyboard instead of creating a UITableViewController (which does that automatically for you).
Check 1 - set delegate programmatically
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
...
}
Check 2 (only for TableView added to a UIViewController in Storyboard)
In the Storyboard through Interface Builder you should also link the tableview's delegate to the File's Owner:
**Check 2 - Step A) **
It can be that instead of having File's Owner explicitly stated on the left bar, it could be that you might have to do it this way:
Check 2 - Alternative Step A)
and then select delegate like this:
Check 2 - Step B)

unable to dequeue a cell with identifier customcellname

I've seen lots of posts about this error, but none of the provided solutions have worked for me. I created the table through the storyboard with a custom prototype cell that I have created a class for. I set the Identifier on the cell.
Cell Identity Inspector: https://i.stack.imgur.com/ebkjA.png
Cell Attributes Inspector: https://i.stack.imgur.com/dIRxu.png
Storyboard table: https://i.stack.imgur.com/UAkeS.png
Code to dequeue cell:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FNListViewCell",for: indexPath) as? FNListViewCell
//filling cell data
// Configure the cell...
return cell!
}
EDIT: I have tried 2 different things to get it to work, which both are getting rid of the error but are instead resulting in the table appearing empty when the page appears.
1) I tried registering the cell with the table using:
self.tableView.register(FNListViewCell.self, forCellReuseIdentifier: "FNListViewCell")
2) I changed the dequeue statement to
let cell = tableView.dequeueReusableCell(withIdentifier: "FNListViewCell") as? FNListViewCell
Both resulted in the cell object having its UILabel elements as null, but after initializing those and setting values I get a blank table.
If you have created a separate XIB for table view cell and a custom class for it, then you will have to register it before using it. If you are using table view in a view controller and have an outlet for your table view, then add this line in viewDidLoad().
tableView.register(UINib.init(nibName: "NameOfYourClass", bundle: nil), forCellReuseIdentifier: "YourIdentifier")
I found the problem and solution. I was programmatically modal presenting the table view using
let ModalController = FileNoteListTableViewController()
self.present(ModalController,animated: true,completion: nil)
I changed it to using a segue defined in the storyboard setup as Present Modally and now the dequeue is working. I'm guessing it is something to do with the controller not being initialized properly when I was doing it manually.

cellForRowAtIndexPath not working properly

I have a tableView in my application and when a user taps on that cell, I need it to go to another view controller that gives more details about the cell they clicked on. When I try to get the cellForRowAtIndexPath by using
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
Nothing is printed to the console so I cant pass that data to another view controller through a segue without knowing that. Is there a reason this would not work?
I am getting the information though this array: var postsArray = [PFObject]() and the table is populated using return postsArray.count
Any help would be greatly appreciated. I may be overlooking it but I am not sure why this would not work as it has worked in other applications of mine.
I have imported delegates as well and have also called table.delegate = self to my viewDidLoad method.
class Profile: UIViewController, UITableViewDelegate, UITableViewDataSource
The full code can be found here: http://pastebin.com/26frZGpa
The line
tableView.delegate = self
as suggested in the very first comment is missing, that's the reason why the delegate method is not called. You can connect the delegate also in Interface Builder.
In your case to perform the segue it's more convenient to connect the segue to the table view cell rather than to the view controller.
The major benefit is that the table view cell is passed as the sender parameter in prepareForSegue and you can get the index path easily with
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let selectedIndexPath = tableView.indexPathForCell(sender as! UITableViewCell)!
}

The label outlet is invalid

I want to declare the 4 labels which in my table prototype cells so that I can retrieve all the data from Parse into the label. As you see in the picture, there're 4 labels, I want each of them have their own outlet, but it showing me the invalid outlet error.
I'm using the Parse to do it, so that the superclass of the prototype cell will be the PFTableViewCell.
class TimetableViewController: PFQueryTableViewController, UITextFieldDelegate{
#IBOutlet weak var lblTime: UILabel!
The error that I got will be like this...
The lblTime outlet from the TimetableViewController to the UILabel is
invalid. Outlets cannot be connected to repeating content.
Therefore, what should I do to avoid this problem exist?
You need to create a custom subclass of UITableViewCell and declare your IBOutlets there. Then you use that subclass instead of the generic UITableViewCell throughout your main view controller.
To reiterate: elements inside a tableview cell belong to the cell, not to the view controller that contains everything.
Edit:
In your view controller, you would conform to UITableView's delegate & datasource protocols (and implement any methods that are relevant to what you're trying to accomplish). You would handle populating (initial) cell data in the follow data source method:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as! TimetableViewCell
// TODO: setup cell data here
return cell
}
Cells are generated on the fly. There is no real connection between the controller and the cell so you cannot connect something in the cell to a controller. Specifically, usually you have multiple cells of the same type ("repeated content") and you can't have all of the labels connected to one outlet in the parent controller.
Typically, what you want to do is declare a class for the cell, e.g.
class MyCell : UITableCell {
#IBOutlet weak var lblTime: UILabel!
}
and add the outlet to it.
For those that errors still exist after you delete the IBOutlet code from your view controller you still need to right click it and delete the old connection. After deleting it the error message will go away.
This cleared all my errors. Hope will help others as well.

Segue.destinationViewController is set to value of sourceViewController

I'm learning about iOS as I write an application that uses a UITableViewController and Core Data to display a list of items, and another view controller that also uses Core Data to configure a variety of additional attributes that are not shown in the table view.
A button in the UITableViewController's navigation bar segues to another view that lets me set a variety of details. This is done using a storyboard "Show Detail" segue, and it works fine.
I want to use the accessory action button in a UITableViewCell to segue to the same detail view controller, so I created another "Show Detail" segue in the storyboard that connects the accessory detail button to the detail view controller (ie: the same kind of segue as the button in the navigation bar)
Confusingly, when I click the detail accessory button at run time, nothing happens, and prepareForSegue is never called.
The UITableView cell style is Subtitle, and I've configured it to have a Detail accessory action. However, the accessory button isn't displayed unless I specifically add it:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: Storyboard.reuseID)
let tone = toneTable[indexPath.row]
cell.textLabel!.text = tone.valueForKey("toneName") as? String
cell.detailTextLabel!.text = tone.valueForKey("toneDescription") as? String
cell.accessoryType = UITableViewCellAccessoryType.DetailButton
return cell
I finally gave up, and called prepareForSeque myself:
override func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath) {
let tone = toneTable[indexPath.row]
self.performSegueWithIdentifier("ShowToneDetail", sender: tone)
}
(I'm using the sender parameter as a convenient place to pass an NSManagedOject)
Now, prepareForSegue gets called, but if I put a breakpoint in prepareForSegue, I see that segue.destinationViewController points to the the source view controller, not the destination view controller. This is unfortunate, because I'd like to pass some values to the new instance of the destinationViewController.
Interestingly, the segue does correctly instantiate the destinationViewController, and passes control to it.
But, I don't understand what's going on. I don't know why I have to call prepareForSeque myself, and I don't know why the segue's destinationViewController isn't set correctly.
What am I doing wrong?
ps: is it just my perception, or is XCode less mature than other IDEs like Eclipse?
You're creating your cells in the wrong way. You should be using dequeueReusableCellWithIdentifier:forIndexPath: to dequeue a cell using the identifier you setup in the storyboard. By doing it the way you are, you're directly instantiating a cell that "knows" nothing about the cell in the storyboard where you added the detail disclosure button, or the segue you made.
I have no idea why the segue.destinationViewController would point to the source view controller. My guess is that it doesn't, and maybe you have your controller classes mixed up.

Resources