separate segue on section header as on table view row - ios

I have a tableview setup whereby every row has its own custom section header. This is done with a prototype cell in the story board. I have a segue to a view controller on the click event of a row. I achieved this by ctrl dragging on the storyboard.
I want my section header to segue to a different controller, however. I ctrl dragged from my header prototype cell to a view controller on the storyboard also.
The result is that both clicking on the row and clicking on the header of the row are bringing me to the same view controller.
It seems the header is linked to the row. Is there any way around this? Could I give my segues identifiers and override the prepare for seg? Or is it possible to have a separate click event on a section header as the rest of the row?
UPDATE:
I have to tried to implement it as follows:
I ctrl dragged from my vc to the destination vc in the storyboard and gave the seg an identifier.
In my viewForHeaderInSection, I have added the following:
let tapper = UITapGestureRecognizer(target: self, action:Selector("seg"))
tapper.cancelsTouchesInView = false
headerCell.addGestureRecognizer(tapper)
return headerCell
my seg func just perform a seg with the identifier I set up as explained above.
func seg(){
self.performSegueWithIdentifier("feedToMembersDetailed", sender: self)
}
In my overridePrepareForSeg, I check the identifier and call the appropriate method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "feedToMembersDetailed"){
//getting in here
getMembersContentFromRow(segue)
}
... extra conditions
}
and finally my getMembersContentFromRow looks as follows:
func getMembersContentFromRow(segue : UIStoryboardSegue){
var membersDetailed = segue.destinationViewController as! MembersDetailedController
if let indexPath = self.feedTableView.**indexPathForSelectedRow()**{
if let selectedId = self.newsFeed?[indexPath.section].authorId{
Prefs.followedId = selectedId.toInt()!
}
println("setting postAuthorPic as \(self.newsFeed?[indexPath.section].authorPic)")
membersDetailed.postAuthorPic = self.newsFeed?[indexPath.section].authorPic
membersDetailed.postAuthorID = self.newsFeed?[indexPath.section].authorId
membersDetailed.postAuthor = self.newsFeed?[indexPath.section].author
}
else{
//getting in here. I need a method that can retrieve indexPath for me
println("could not get selected row")
}
}

Ok here it is, I am not writing code, just the steps you need to follow
Remove the segues you have created from your row and headers. Just assign SegueIdentifier for the controllers to be opened, say SegueIdentifierForRow and SegueIdentifierForSection.
Since there is no action in tableview headers, you need to add a custom action may be an UIButton or, UITapGestureRecognizer. Cell selection you can leave as it is. And to determine section selection you can set tag for each section.
On Row CellSelection manually initialise ViewController by using identifier SegueIdentifierForRow, and same for section using different identifier SegueIdentifierForSection.
Follow above you should be able to do whats required.
Cheers.

You would need to implement viewForHeaderInSection: method and add a UITapGestureRecognizer to a view which would be retuned as header view. You can then handle the tap on your table section headers to go to different View Controller.

Related

How do I tell which button called another view in swift 4?

I want to know which button called the second view which displays a list of the type of items. The tableViewCell contains an array of all the items. For example, if the user taps on burgers he gets a list of all the burger items. I have connected each button to the second view individually but it seems like there has to be a better way like connecting it to the touchButton method that all buttons are connected to but I'm not sure how to do this. Also, should the array of items be in tableViewController or is tableViewCell fine?
First of all instead of giving each button segue for same view, i recommend you to use only one segue.
One approach is to simply use a indicator int or string depending upon your logic in items table view and assign it accordingly in prepare for segue method by getting destinationVC. And handle the indicator on list items view on loading. (in this approach you have only one segue and you will be able to perform the work).
As far as table view approach is concerned. use tableview for list of items and use tableViewCell for individual items.
In theory :
If you are moving onto the next ViewController from current , you can create a variable inside the next View Controller and while moving from current VC to next, you can fetch the name of the Button inside the #IBAction method and create instance of next VC and access that variable (created earlier) and assign the name of that button to that variable
Code :
class CurrentViewController: UIViewController {
// Your other code goes here
#IBAction func actionButtonTapped(_ sender: UIButton) {
// Here we fetch the name of the button tapped
let nameOfButtonTapped = sender.titleLabel!.text
// Here we create instance of NextViewController
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "#yourNextVCIdentifierHere") as! NextViewController
// Here we assign the name of the button tapped to the variable of NextViewController so we can access it there
nextVC.buttonNameThatWasClicked = nameOfButtonTapped
self.present(nextVC, animated: true, completion: nil)
}
}
class NextViewController: UIViewController {
var buttonNameThatWasClicked: String?
override func viewDidLoad() {
super.viewDidLoad()
print(buttonNameThatWasClicked!)
}
}
Here, we can connect All the Buttons to a single #IBAction by control-dragging all the buttons to the name of the #IBAction method

Swift 3 - filter tableview from different view controller

I have built an app that centers around a pretty tableview that I've built.
I have setup a secondary view controller as a menu that is presented modally, and I would like to filter the tableview by selecting one of the buttons on the secondary view controller.
For example, each cell has a City assigned to it. In the menu, I'd like to be able to click a city and filter the tableview to only show cells with that city.
I have too much code to paste, and I'm confident I can solve this problem with a smidge of direction.
Thanks for your help!
You can do this with an unwind segue from your second view controller's buttons back to your table view controller.
In your table view controller, say,
func unwindToTableView(_ segue: UIStoryboardSegue) {
switch segue.identifier {
case "FilterNames":
filterByName()
etc…
}
}
or you could have different unwind funcs for each filter…
func unwindAndFilterName(_ segue: UIStoryboardSegue) {
filterByName()
}
etc
To hook up an unwind segue, just add the method to your table view controller, then in your storyboard, drag from the button on the second view controller to it's Exit icon. The segue func should appear in the list
To do this you would like to have separate DataSource layer in the application to have move clear code.I will write small example for you how it is possible to implement.
For example you have class DataSource. With information that you are showing. In my case it is cities. Now when I would like to do sorting I will call sortAlphabetically() and reload tableview. It is quite simple way and you're solution really depends on how you are working with UITableView.
class DataSource {
var cities = ["Lviv", "Lutsk", "Kiev", "Rivne"]
func sortAlphabetically() {
cities = cities.sorted { $0 < $1 }
//reload tableview hear
}
}
Best way to do so is to use delegates, add a protocol to your filter view controller and a delegate function in tableView that filters datasource for tableView. Don't forget to assign your table view controller as the delegate before you segue to the filter viewcontroller
Best way to do so is to use delegates, add a protocol to your filter view controller and a delegate function in tableView that filters datasource for tableView. Don't forget to assign your table view controller as the delegate before you segue to the filter viewcontroller
Before your filterViewController
protocol FilterViewControllerDelegate {
func tableViewCriteria(criteria: AnyObject)
}
In your filterViewController:
var delegate: FilterViewControllerDelegate?
In the class declaration of tableViewController, add FilterViewControllerDelegate
class MyTableViewController: UITableViewController, FilterViewControllerDelegate{
Don't forget to set the FilterViewControllerDelegate to self before you segue to the filterView:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showFilter" {
if let fvc = segue.destination as? FilterViewController{
fvc.delegate = self
}
}
}
Implement the func in tableView that will update tableView data source based on the chosen criteria:
//In myTableViewController
func tableViewCriteria(criteria: AnyObject) {
//update tableView data source base on criteria here
return
}
Finally, call the delegate function from filterView whenever you need to return to tableview:
self.delegate?.tableViewCriteria(criteria: foo)
Voila! :)

Swift - Can not detect button action in uitableviewcell after set auto layout

There is a button in my custom tableviewCell, when I press the UIButton, it will open another view in my app.
Everything is okay after I try to active the auto layout attribute.
And even I don't set any constraint to my button, it still can not be
detected and shift to another view.
A snapshot image here
Can anyone help me ?
UPDATE:
Thanks for Korpel, rose and Tobonaut.
Yes I had create the segue on the button to another view, and it worked before I set the attribute of autoLayout. I was sure I added the segue and identifier both on the storyboard and the code .
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier=="RemindSegue" {
let destination = segue.destinationViewController as! RemindTimeController
let senderButton = sender as? UIButton
let indexPath = NSIndexPath(forRow: (senderButton?.tag)!, inSection: 1)
destination.delegate = self
}
}
After I set the autoLayout option, I could only click on my custom tableCell, which was dynamically created on the runtime. And the click on the button didn't work anymore.
The button's still there, there was no constraint added to it.
Ok, I find the answer of it.
I added the following code in my custom tableViewCell when initiate...
which disabled my button to use.
But I don't really understand the reason behind it...
self.contentView.translatesAutoresizingMaskIntoConstraints = false

Accesing parent cell labels swift

I have a button placed inside a TableViewCell, the button triggers a action which passes data to another ViewController and displays it. Is there any way to access the labels of the particular cell that I clicked?
The cells are being created and populated from an API.
For example, I have 10 cells, all having different labels inside. I need to access the labels of the cell that I clicked (Or the cell that the button I clicked on is a child to) and pass this data to my other ViewController
Cheers!
I solved this by giving the button tag an ID from my API and passing this to the other ViewController.
That works, I had just figured this out:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
let indexPath = self.tableView.indexPathForSelectedRow()
let cell = self.historyViewTable.cellForRowAtIndexPath(indexPath!)
println(cell.cellLabel.text!)
}

How do I make multiple tableview cells to lead corresponding view controllers?

I am making an app with a tableViewController as the initial view controller. It obviously has a list of items in tableview cells. I want each of the tableView cell to lead to a different View controller. Here is an example of my home screen:
![enter image description here][1]
What I am trying to achieve, for example, is that the tools cell will take me to a View controller with details about tools. And when I click on weapons, it should take me to a view controller with details about weapons. I already have the view controllers set up, but I don't know how to create segues to each view controller. NOTE: I made these cells in code and not in my storyboard. I made an array of items and I used indexpath.row to display them.
Thanks for any help!
nstead of connecting and creating segue from individual cells, you can connect all those segues from the View Controller button, lying below your view in your storyboard. In this case, you will have multiple segues and none of them will be individually connected to cells. And when segues are ready, you can use this method for moving on to the next View Controller depending on which cell is tapped from the tableView.
[self performSegueWithIdentifier:#"yourSegue" sender:nil];
You just have to check which cell is tapped and then perform the appropriate Segue on tap.
Look out for the yellow button as shown below your View Screen in your storyboard.
Drag and drop a segue from that button onto the View Controller that you want to connect.
Hope this helps.
This was extremely helpful and what I needed to do to get rid of the segue from the table view cell. Doing exactly what you suggested above and adding this to the tableViewDidSelectRowAtIndexPath...
override func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if let indexPath = self.tableView.indexPathForSelectedRow
{
rowSelected = indexPath.row
sectionSelected = indexPath.section
//Transition to the Set Details VC
if indexPath.section == 0
{
print("Set Details")
self.performSegueWithIdentifier("Segue1", sender: self)
}
//Transition to the Info Section
else if indexPath.row == 0 && indexPath.section == 2
{
print("About Page")
self.performSegueWithIdentifier("Segue2", sender: self)
}
}//End If IndexPath
}//End DSRAIP

Resources