SWIFT if statement and segue - swift

I have a problem with if statement and segue
can I make a connection between them !
I have an array of these states ["Florida","NY"]()
my idea, for example, if I clicked "Florida"<(this is "string") on table view
I want the segue moves me from this table view to another table view
and if I clicked "NewYork" on tableView I want the segue moves me from this table view to another that has information about NY
thanks

You could do something like this:
class SelectCityViewController : UITableViewController {
// store a reference to use in transition
var selectedCity : String?
let cities : [String] = ["New York", "San Francisco", "Los Angeles"]
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = //TODO: your implementation here
cell.textLabel?.text = cities[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedCity = cities[indexPath.row]
performSegueWithIdentifier("YOUR_SEGUE_IDENTIFIER", nil)
}
override func tableView(tableView: UITableView, numberOfItemsInSection section: Int) -> Int {
return self.cities.count
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let vc = segue.destinationViewController as? CityDetailViewController {
vc.selectedCity = self.selectedCity!
}
}
}
Then your second view controller would have a variable with your selected city stored in it so you could setup your content accordingly
class SelectedCityDetailViewController : UITableViewController {
// Set during the segue
var selectedCity : String!
// The rest of your methods
}

you can do something like this in didSelectRowAtIndexPath.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
if let text = currentCell.textLabel?.text {
if text == "Florida"{
// segue tableview controller
} else if text == "NY" {
//another segue
}
}
}

Take a viewController and add a tableView. Add two another view controllers, one for the NY info and the other containing one more uiTableView. Create two segues from main controller to the other two. Name the segues so that you can refer to them in the code. In didSelectRowAtIndexPath add the following Code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
if indexPath.row == 0{
self.performSegueWithIdentifier("florida", sender: nil)
}else if indexPath.row == 1{
self.performSegueWithIdentifier("ny", sender: nil)
}
}
Please check this Link. I have created a demo project for you. I think you are a starter to the iOS development. Carry On!! :)

Related

How to make a push segue when a specific UITableViewCell is selected

I am working on my first iOS app and new student to swift.
Everything is working however I am having trouble figuring out how to segue from a specific cell to a third view controller. I have a IOS UITableView with three sections and a total of (44) cells. All cells when tapped segue to one DetailVC titled: showProductDetai which is fine. The problem that I am having is that I need to have only (1) particular cell in section 0 row 5 in the UITableView to go to its own ViewController in which I titled: second view controller instead of the normal showProductDetail VC. Is there an intelligent way to make the specific cell in section 0 row 5 of the tableView go to second view controller when selected?
Here is my current code that is working. How would I code to make the changes?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductTableViewCell
// Configure the cell...
let productLine = productLines[indexPath.section]
let products = productLine.products
let product = products[indexPath.row]
cell.product = product
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let productLine = productLines[section]
return productLine.name
}
// Mark: UITableViewDelegate
var selectedProduct: Product?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let productLine = productLines[indexPath.section]
let product = productLine.products[indexPath.row]
selectedProduct = product
performSegue(withIdentifier: "ShowProductDetail", sender: nil)
}
// Mark: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "ShowProductDetail" {
let DetailVC = segue.destination as! DetailViewController
DetailVC.product = selectedProduct
}
}
see what I did here? You can use the indexPath parameter to get the section & row the user touched, and then you can set up your programmatic segue.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if ((indexPath.section == 0) && (indexPath.row == 5)) {
performSegue(withIdentifier: "GoToSecondViewController", sender: nil)
} else {
let productLine = productLines[indexPath.section]
let product = productLine.products[indexPath.row]
selectedProduct = product
performSegue(withIdentifier: "ShowProductDetail", sender: nil)
}
}
Write a segue code for the desired section and row:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 && indexPath.row == 5 {
//Perform Segue
} else {
//Rest of the functionality
}
}
Make sure you have connected proper Sugues and given proper identifiers in Storyboard.
You don't need to write prepare Segue method

How to pass data through table views

my data structure sample..
Sports
Bat-and-ball
Baseball
Softball
Cricket
Hockey
Field Hockey
Ice Hockey
Roller Hockey
Engineering
Computer Science
Software Engineer
Electrical Engineer
Here I have three level data as you can see . but by default in tableview it provides only upto 2 level. how can i display the third level data.
I am only able to show the 1st level data in sections and second level data in rows using customcell. now where to display the third level data. so that i can iterate based on number of rows..
my screen should be like that..
There are plenty of ways to do it.
I will list a couple of them later.
But first you might think about whether it is a good user experience to show 3 levels of data in one table view. It might be difficult for the user to navigate through it.
So these are some options.
Show the top level data (let's call it a category) in a selector(dropdown) and then in a table view just have two levels (sections and rows) for the selected category.
Here is an example of such dropdown view:
https://github.com/PhamBaTho/BTNavigationDropdownMenu
If you really need to show a list with 3 levels of data you can have a table view, which will show the top level data as a section and second level as a row. For each row the corresponding cell will contain inside a table view (or might be just a stack view) showing just the rows for the 3rd level.
you can add table in custom cell and 2nd and third level data can display on that inner table.
This code ran beautifully on my device.
Storyboard
TableViewController1
import UIKit
class TableViewController1: UITableViewController {
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return group1.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = group1[indexPath.row].title
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segue1" {
let indexPaths = self.tableView!.indexPathsForSelectedRows!
let indexPath = indexPaths[0] as NSIndexPath
let vc = segue.destinationViewController as! TableViewController2
vc.currentGroup = group1[indexPath.row].title
}
}
}
TableViewController2
import UIKit
class TableViewController2: UITableViewController {
var currentGroup: String?
var filteredData = [Data]()
override func viewDidLoad() {
super.viewDidLoad()
for data in group2 {
if data.group == currentGroup {
filteredData.append(data)
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = filteredData[indexPath.row].title
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segue2" {
let indexPaths = self.tableView!.indexPathsForSelectedRows!
let indexPath = indexPaths[0] as NSIndexPath
let vc = segue.destinationViewController as! TableViewController3
vc.currentGroup = group2[indexPath.row].title
}
}
}
TableViewController3
import UIKit
class TableViewController3: UITableViewController {
var currentGroup: String?
var filteredData = [Data]()
override func viewDidLoad() {
super.viewDidLoad()
for data in group3 {
if data.group == currentGroup {
filteredData.append(data)
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = filteredData[indexPath.row].title
return cell
}
}
Data Class
import Foundation
class Data {
var title: String
var group: String?
init (title: String, group: String?) {
self.title = title
self.group = group
}
}
let group1 = [Data(title: "Sport", group: nil), Data(title: "Engineering", group: nil)]
let group2 = [Data(title: "Hockey", group: "Sport"), Data(title: "CS", group: "Engineering")]
let group3 = [Data(title: "Ice Hockey", group: "Hockey"), Data(title: "Software Engineer", group: "CS")]
P.S. I hate to make things complicated.
Happy hacking!

Segue not sending correct cell info in Swift

I have a tableView that triggers a segue to a detail view when a cell is pressed. The table contains a list of users that the currentUser is friends with. Pressing the cell loads the view for that user (name, profile, etc). It's a very simple app I'm creating to learn how to program.
The problem is that when I press on a cell, it's always loading the user info for the last user in the table (and also happens to be the most recent "friend" that the user made). I have a feeling that the issue is with an if statement I have in the tableView function:
extension MatchesViewController: UITableViewDataSource
{
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return numberOfMatches
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MatchCell", forIndexPath: indexPath)
if PFUser.currentUser()!.objectId == self.user1.objectId{
let user = matchesResults[indexPath.row]["user2"] as! PFUser
cell.textLabel?.text = user["first_name"] as! String
self.viewUser = user
}
if PFUser.currentUser()!.objectId == self.user2.objectId{
let user = matchesResults[indexPath.row]["user1"] as! PFUser
cell.textLabel?.text = user["first_name"] as! String
self.viewUser = user
}
return cell
}
}
Here's the segue code, but I don't think there is an issue with it (although I could be wrong):
extension MatchesViewController: UITableViewDelegate
{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("UserSegue", sender: "viewUser")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "UserSegue") {
let destinationVC = segue.destinationViewController as! UserViewController
destinationVC.user = self.viewUser
}
}
}
Any ideas? If there is an issue with my tableView If statement, how can I fix it?
Thanks!
You can get the user object by indexPath, than pass it through the sender parameter of the performSegueWithIdentifier method
extension MatchesViewController: UITableViewDelegate
{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let user:PFUser?
if PFUser.currentUser()!.objectId == self.user1.objectId{
user = matchesResults[indexPath.row]["user2"] as! PFUser
}
if PFUser.currentUser()!.objectId == self.user2.objectId{
user = matchesResults[indexPath.row]["user1"] as! PFUser
}
self.performSegueWithIdentifier("UserSegue", sender: user)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// sender is the user object
if (segue.identifier == "UserSegue") {
let destinationVC = segue.destinationViewController as! UserViewController
destinationVC.user = sender // maybe you need cast sender to UserObject
}
}
}

Custom UITableViewCells repeating when navigating to viewcontroller

I am making a running app, and would like the user to see the races/marathons in their city. When clicking on the cell the user is navigated to a new view controller with details of the marathon. But upon pressing the back button to go back to the table the cells repeat. for example, if scrolling on the table it will display cell 1, cell 2,cell 3, cell 4,cell 1, cell 2,cell 3, cell 4 and will repeat more every time I navigate to the view controller with the table.
The code for the table is:
//MARK: TableView
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exhibitions.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let singleCell: marathonTableViewCell = tableView.dequeueReusableCellWithIdentifier("marathonCell") as! marathonTableViewCell
singleCell.marathonName.text = exhibitions[indexPath.row]
singleCell.entryNumber.text = "\(entryNumber[indexPath.row])"
singleCell.entries.text = "\(entires[indexPath.row])"
return singleCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("marathonDetail", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "marathonCardDetail"){
var upcoming: marathonDetailViewController = segue.destinationViewController as! marathonDetailViewController
let indexPath = self.marathonsTableView.indexPathForSelectedRow!
let currentCell = marathonsTableView.cellForRowAtIndexPath(indexPath) as! marathonTableViewCell
let marathonEvents = currentCell.marathonName.text
upcoming.nameMarathon = marathonEvents
self.marathonsTableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
I am using swift, Xcode 7, and Parse as my backend.
I think u have to init ur array before update tableview.
When u click back button, tableview may refresh.
So make some code that makes ur array new, and then call tableview.reloadData()

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.