Resign First Responder On Push To Detail - swift

I was wondering how to resignFirstResponder whenever I switch to my detailView in the tableView, is this something I can implement in my prepareForSegue or somewhere else.
Here is my prepareForSegue code.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DetailView") {
let VC = segue.destinationViewController as! DetailViewLemon
if let indexPath = self.tableView.indexPathForSelectedRow {
let Make = self.resultSearchController.active ?
filteredTableData[indexPath.row] as String :
tableData[indexPath.row] as String
VC.sentData1 = Make
}
}
}

Any UIView (and UIWindow as well, as it is UIView subclass) has method
func endEditing(force: Bool)
This will resign any current first responder descendant in the hierarchy of the view on which you call this method.
So you can call it on the view of the previous detail view controller or at the whole application's window from the prepareForSegue or any other logic point of your program.

Related

Make a segue to a tableview controller from a view controller

I am trying to make a segue to a table view controller when a button is tapped in my view controller programmatically. Here is my code:
#objc func editProfileButtonAction(sender: UIButton!) {
print("ButtonTapped")
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
if identifier == "EditProfile" {
var editProfileTableViewController = segue.destination as! EditProfileTableViewController
editProfileTableViewController = self
}
}
}
}
I really could use some help. I also need to make a segue to a collection view controller using a button in the same view controller.
Okay to clarify that. There is no way to create a segue programmatically. Segues are the arrows on storyboard linking from one to another VC. They are called with: performSegue. This calls the function prepare.
If you want to show a new VC when hitting a button (without segue), then you use the present(VC(), animated: true, completion: nil) } inside the button function. The VC is presented modally.
#objc func editProfileButtonAction(sender: UIButton!) {
print("editProfileButtonAction")
present(EditProfileTableViewController(), animated: true, completion: nil)
}
Make sure, that the segue in the Storyboard has exactly the identifier: "EditProfile". Normally I'm writing identifiers with lower letter in the beginning. You also need to prepare for Segue. For example set the delegate:
// Set ViewController class as the delegate of the EditProfileTableViewControllerDelegate protocol
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
if identifier == "EditProfile" {
let editProfileTableViewController = segue.destination as! EditProfileTableViewController
editProfileTableViewController = self
}
}
}
At one point in my coding time, I deleted all my storyboard because of too many error's that I could hardly solve. Now I'm doing it all programmatically. At first it was a bit hard to set up all the view's by myself but after all I'm very glad I'm not using storyboards anymore. For some stuff I need xib's, and for testing storyboard. Just if you're interested: the most iOS programmers are using storyboard, so it's okay if you go on with that.
The advantage of doing it all programmatically is that there are no segue's anymore. So just present, and on navigation VC's push, pop, ...

Segue is being executed twice

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedClubState = stateNamesForDisplay[indexPath.row]
self.performSegueWithIdentifier ("Cities", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var clubsToPassToCitiesViewController = [clubObject]()
if segue.identifier == "Cities" {
for club in clubsForTable{
if club.clubState == self.selectedClubState{
clubsToPassToCitiesViewController.append(club)
}
}
let citiesView = segue.destinationViewController as? citiesViewController
citiesView?.clubsForChosenCity = clubsToPassToCitiesViewController
}
}
Segue is being executed twice leading to the next VC. How can I prevent this from happening?
Delete the current segue in storyboard. Then CTRL-drag from the viewController (not the cell) to the next view controller and name it "Cities". Now, when you select a cell, the didSelectRowAtIndexPath() will fire first and will call performSegueWithIdentifier()
However, if all you're looking to do in the didSelectRowAtIndexPath() is get the row that performed the segue, you can maintain your original setup of having the cell segue from the storyboard, remove didSelectRowAtIndexPath() and in prepareForSegue() do:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let indexPath = self.tableView.indexPathForSelectedRow {
self.selectedClubState = stateNamesForDisplay[indexPath.row]
}
var clubsToPassToCitiesViewController = [clubObject]()
if segue.identifier == "Cities" {
for club in clubsForTable{
if club.clubState == self.selectedClubState{
clubsToPassToCitiesViewController.append(club)
}
}
let citiesView = segue.destinationViewController as? citiesViewController
citiesView?.clubsForChosenCity = clubsToPassToCitiesViewController
}
}
You are the one executing the segue twice — once automatically in the storyboard (because your segue emanates as an Action Segue from the cell prototype), and once in code when you say self.performSegueWithIdentifier. If you don't want the segue executed twice, remove one of those.
Personally, my recommendation is that you delete didSelectRow entirely and move your self.selectedClubState assignment into prepareForSegue.

How to Push ViewController in UITableViewCell's #IBAction func

I have a UITableViewController and UITableViewCell and Cell's XIB Files.
My question is how to push UIViewController from cell?
in UITableViewCell.
#IBAction func pushBtnTapped(sender: AnyObject) {
// navigate to post view controller
let guest = self.storyboard?.instantiateViewControllerWithIdentifier("GuestCollectionVC") as! GuestCollectionVC
self.navigationController?.pushViewController(guest, animated: true)
}
I got an error message. self.storyboard is not UITableCell's member.
I know there is another way to implement this. But I have to implement in TableViewCell.
Ideally you'd push from the table view controller, in the didSelectRowAtIndexPath method call. Why do you say you have to implement it in the cell? There are other ways you could do that but from what you're saying this might be the best shot...
self.performSegueWithIdentifier("YourSegueId", sender: nil)
Then in prepareForSegue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//get the index path of the selected row
let indexPath = self.tableView.indexPathForSelectedRow
//just an example if you want to pass something to the other vc
let item = self.responseItems[indexPath!.row]
if segue.identifier == "YourSegueId" {
YourVC = segue.destinationViewController as! YourVC
YourVC.item = item
}
}
If you want to do it from the button you could do something like this in the prepareForSegue method... now you have the button and its index path
let button = sender as! UIButton
let view = button.superview
let cell = view?.superview as! YourCell
let indexPath = tableView.indexPathForCell(cell)

How to get a ViewController to segue to itself repeatedly.

SWIFT: In my storyboard, embedded in a NavigationController, I have a ViewcontrollerA which needs to either present itself repeatedly OR present ViewcontrollerB based on an if clause.
I've implemented the logic in the prepareForSegue method. I've drawn a segue from ViewcontrollerA to ViewControllerB.
if (someClause == true)
{
let svc = segue.destinationViewController as! ViewControllerA
} else {
let svc = segue.destinationViewController as! ViewControllerB
}
Executing this code results the following error:
Could not cast value of type 'ViewControllerB' to 'ViewControllerA' .
That's because there is no segue from ViewControllerA to ViewControllerA. The segue is from ViewControllerA to ViewControllerB.
Is there a way for one "Button" to have multiple segues? One to ViewControllerA (itself) and one to ViewControllerB. I know this is possible for TableViewCells.
Side note, I have managed to get instantiateViewControllerWithIdentifier followed by a call to presentViewController to do what I want, but that destroys my NavigationStack and TabBar. I DONT want to go this route because it seems like a lot of patch work.
You should create a segue between from ViewControllerA to ViewControllerB, not the button to ViewControllerB. Then do something like:
#IBAction func buttonPressed(sender: UIButton) {
if (someClause == true)
{
// Stay on ViewControllerA
} else {
performSegueWithIdentifier("showB", sender: AnyObject)
}
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "showB") {
let _ = segue.destinationViewController as? ViewControllerB
}
}

How to know which segue was used using Swift?

I have a main viewController and a detailsViewController. The detailsViewController has 2 buttons. Both buttons are segues back to the main controller but I want to customize the main viewController based on which segue was used. What is the best way to check which segue was used to reach a viewController so that the main viewController can be customized depending on that? - if segue1 leads to the the main viewController then I want label1 hidden. if segue2 leads to the main viewController, then I want label2 hidden.
In Main View Controller create a variable , something like
var vcOne : Bool = true
Now in DetailsViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "segue_one"
{
let mainVC : MainViewController = segue.destinationViewController as! MainViewController
secondVC.vcOne = true
}
else if segue.identifier == "segue_two"
{
let mainVC : MainViewController = segue.destinationViewController as! MainViewController
secondVC.vcOne = false
}
}
Now in MainView Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//Now check here for which segue
if(vcOne)
{
// implement for button one click
}
else
{
// implement for button two click
}
}
Hope it helps you
I'd do something like to check which segue was used. You have to set an identifier to the segue in the storyboard though!
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "yourIdentifier" {
let yourVC = segue.destinationViewController as? yourViewController
//do magic with your destination
}
}
There is a option for setting Identifier for segue. This should be unique identifier. So that you can identify which segue is activated.
Ex:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Identifier1" {
let firstVC = segue.destinationViewController as? FirstViewController
} else if segue.identifier == "Identifier2" {
let secondVC = segue.destinationViewController as? SecondViewController
}
}