Push different UIView for each row of UITableView - ios

I'm trying to push a new view when I select a row.
let identifiers:[String] = ["vc1", "vc2", "vc3", "vc4", "vc5"]
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let identifier = identifiers[indexPath.row]
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: UINavigationController = storyboard.instantiateViewControllerWithIdentifier("\(identifier)") as! UINavigationController
self.presentViewController(vc, animated: true, completion: nil)
}
All the different views called with this tableView have their own class and Storyboard ID.
At the moment I get the error:
Could not cast value of type 'testApp.CalculatorViewController' to 'UINavigationController'

I think you are trying to cast UIViewController to UINavigationController.
Please try this. This may help you.
let identifiers:[String] = ["vc1", "vc2", "vc3", "vc4", "vc5"]
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let identifier = identifiers[indexPath.row]
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: UIViewController = storyboard.instantiateViewControllerWithIdentifier("\(identifier)") as! UIViewController
self.navigationController?.pushViewController(vc, animated: true, completion: nil)
}

Related

Need to double tap on cell to present modally VC

I am generating table cell.
cell2 = settingsTableView.dequeueReusableCell(withIdentifier: "ModuleCell", for: indexPath) as! ModuleCell
It looks fine, the cell has tag = 2000.
In override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath), I am checking the tag end if tag == 2000 I want to present modal view. I am doing that in this way
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let modalView = storyboard.instantiateViewController(withIdentifier: "ModalView")
present(modalView, animated: true, completion: nil)
Then in modalView I have a button which should dismiss modalView, what's happening as expected.
#IBAction func saveAndClosePopup(_ sender: UIButton) {
UserDefaults.standard.removeObject(forKey: "ActiveCantachoOptions")
UserDefaults.standard.set(Modules.activeCantachoOptions, forKey: "ActiveCantachoOptions")
self.dismiss(animated: true, completion: nil)
}
However, when I want to immediately present modalView again, sometimes it's okay, but sometimes I need to hit two times on the cell, which should show modalView. After the first hit, there is no difference if I hit the cell again in 1 second or in 30 seconds. The modalView will appear after the second one. What is the cause?
Try this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let modalView = storyboard.instantiateViewController(withIdentifier: "ModalView")
self.present(modalView, animated: true) {
tableView.deselectRow(at: indexPath, animated: false)
}
}

fatal error while unwrapping a view controller value

I have a few viewcontrollers in storyboard with certain identifiers and when I try to access them like this:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let mainViewController = sideMenuController!
let vcName = identities[indexPath.row]
let viewController: UIViewController! = storyboard?.instantiateViewController(withIdentifier: vcName)
let navigationController = mainViewController.rootViewController as! NavigationController
navigationController.pushViewController(viewController, animated: true)
mainViewController.hideLeftView(animated: true, completionHandler: nil)
}
The app crashes. This line is detecting that the value is nil. Can anyone explain how this is nil while unwrapping?
navigationController.pushViewController(viewController, animated: true)
After several attempts I managed to get rid off the fatal error. However the view controller still does not appear upon tapping on the table view item.
Original Project -
link
Edited Project -
link
Well, the project is a little "messed up" :-)
First: You need to somehow get "the" UINavigationController (or derived class).
Since your LeftViewController is not on the navigation stack, it does not have a navigationController set. So, you need to get it from the mainViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
print(storyboard)
let mainViewController = sideMenuController!
let vcName = identities[indexPath.row]
let viewController: UIViewController! = storyboard.instantiateViewController(withIdentifier: vcName)
print(viewController)
if let theNavigationController = mainViewController.rootViewController as? UINavigationController {
print("Gotcha")
theNavigationController.pushViewController(viewController!, animated: true)
mainViewController.hideLeftView(animated: true, completionHandler: nil)
}
}
Second, there is still a problem:
The view controller with identifier 'A' is of type EngineTunningParamteres, derived from UINavigationController. You cannot push a navigation controller onto an existing navigation controller. Therefore, we have to change the class, too:
class EngineTunningParamteres: UIViewController {
override func viewDidLoad() {
print("hi") }
}
Now it works. You're welcome.
let viewController: UIViewController!
is an Optional, with this ! you are just telling the compiler "I know this may be nil but don't worry, at run time it will never be nil".
If you want to get rid of this Optional you have to unwrap the storyboard :
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let mainViewController = sideMenuController!
let vcName = identities[indexPath.row]
let viewController = storyboard!.instantiateViewController(withIdentifier: vcName)
let navigationController = mainViewController.rootViewController as! NavigationController
navigationController.pushViewController(viewController, animated: true)
mainViewController.hideLeftView(animated: true, completionHandler: nil)
}

Data not appearing in view controller

I have been trying everything I could but nothing seems to work. I am trying to pass firebase user information from one view controller to another, but it never appears.
It starts from a table view
The table view is populated with users that are being pulled from my firebase database. When the user selects a cell the following code gets executed:
I reference function "showProfileControllerForUser" as a way to transport the data of the cell that was selected
var mainProfile: userProfileNavigator?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user1 = self.users[indexPath.row]
self.mainProfile?.showProfileControllerForUser(user3: user1)
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc: UINavigationController = storyboard.instantiateViewController(withIdentifier: "mainNavProfile") as! UINavigationController
self.present(vc, animated: true, completion: nil)
}
In "userProfileNavigator" is where the function that was used before is. The function passes the information that was collected and passes that to the final destination.
func showProfileControllerForUser(user3: User){
mainProfile?.user2 = user3
}
Finally, "mainProfile" is where I want the data to be passed to.
var user2: User?{
didSet{
navigationItem.title = user2?.name
}
I could imagine this being very confusing, I can provide anymore information or clarity if needed
attempted to setup table as such:
var mainProfile: mainProfile?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user1 = self.users[indexPath.row]
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc: UIViewController = storyboard.instantiateViewController(withIdentifier: "mainProfile")
self.mainProfile?.user2 = user1
self.present(vc, animated: true, completion: nil)
}
And the ViewController in which the information is being passed as such:
import UIKit
import Firebase
class mainProfile: UIViewController{
#IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print("lets see if this is the new user", user2.name as Any)
}
var user2 = User()
}
but it still comes up as "nil"
If I understood your question right, then you have two ViewControllers. One which contain UITableView, and another is ShowProfileControllerForUser.
In ViewController which contain UITableView, code this:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user1 = self.users[indexPath.row]
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc: UINavigationController = storyboard.instantiateViewController(withIdentifier: "mainNavProfile") as! UINavigationController
vc.user3 = user1
self.present(vc, animated: true, completion: nil)
}
Also, I am not sure if you're presenting the right ViewController.
In your ShowProfileControllerForUser.swift,
var user3 = User // declare a variable with proper type.
Now in your viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
showProfileControllerForUser(user3)
}
Edit:
var mainProfile: mainProfile?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user1 = self.users[indexPath.row]
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc: UIViewController = storyboard.instantiateViewController(withIdentifier: "mainProfile")
//self.mainProfile?.user2 = user1 // Instead of this line
vc.user2 = user1 // use this line
self.present(vc, animated: true, completion: nil)
}
If you want to open controller with that passed value, you can set that value after instantiating it
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc: UINavigationController = storyboard.instantiateViewController(withIdentifier: "mainNavProfile") as! UINavigationController
// this is what your showProfileControllerForUser doing
vc.user2 = user1
self.present(vc, animated: true, completion: nil)

Swift / tableView pass data with instantiateViewControllerWithIdentifier

I have an array of BackendlessUsers filled within a tableView. How can I pass the user within the didSelectRowAtIndexPath function?
var deejays: [BackendlessUser] = []
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
**let user = deejays[indexPath.row]**
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("DJProfileAsUserVC") as! DJProfileAsUserVC
dispatch_async(dispatch_get_main_queue()) {
self.presentViewController(vc, animated: true, completion: nil)
}
}
Help is very appreciated.
Create a var user: DJProfileAsUserVC! in DJProfileAsUserVC and after that to this:
let user = deejays[indexPath.row]
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("DJProfileAsUserVC") as! DJProfileAsUserVC
vc.user = user

In Swift, how to grab object id from UITableView and delete object based on object id?

I don't know how to grab object id from UITableView after user select from it and in another view controller, I want to delete the object based on object id that I already fetch from previous one.
UITableView
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
/* grab object id here and pass to NSUserDefault*/
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let deleteViewController = storyBoard.instantiateViewControllerWithIdentifier("accessView") as DeleteViewController
self.presentViewController(deleteViewController, animated:true, completion:nil)
}
DeleteViewController
/* Delete object happen here*/
You can set a property in DeleteViewController and pass the value to it when initializing the view controller.
class DeleteViewController {
var objectId: Int?
}
// Previous view controller
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Grab your object from the data source
let object = dataSource[indexPath.row]
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let deleteViewController = storyBoard.instantiateViewControllerWithIdentifier("accessView") as DeleteViewController
// Pass the Id
deleteViewController.objectId = object.objectId
self.presentViewController(deleteViewController, animated:true, completion:nil)
}
I already found the answer.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let data: NSManagedObject = myList[indexPath.row] as NSManagedObject
let objectId = data.valueForKeyPath("objectId") as? String
NSUserDefaults.standardUserDefaults().setObject(objectId, forKey: "objectId")
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let deleteViewController = storyBoard.instantiateViewControllerWithIdentifier("accessView") as DeleteViewController
self.presentViewController(deleteViewController, animated:true, completion:nil)
}

Resources