Alright let's say I have two ViewController, FirstViewController that contains a table and the CustomCell. I set up the action of the button in the CustomCell and it does what it is supposed to do but I want to call the [tableView reloadData] function in my FirstViewController.
What is the proper way of calling this function after the button is selected? Is there a way to set up something in FirstViewController that gets called when the Button in the other Class is selected?
You're best bet, if I understand your question correctly, is to use the Delegate Protocol in the second view, which returns a message to the first view controller.
See my answer here on how to setup a delegate:
How to declare events and delegates in Objective-C?
Related
I have TableViewController with a custom cells.
For table is responsible class:
#interface CustomTableViewController : UITableViewController
For cells is responsible class:
#interface CustomTableViewCell : UITableViewCell
The ImageView are located in cell of table.
How I can open new controller when I click(touch) at ImageView inside cells?
As it appears I must to use UIViewController near UITableViewCell that to open new viewController, is not?
Usually this kind of stuff is handled inside UITableViewDelegate method didSelectRowAtIndexPath. However the table view calls this method when the entire cell is tapped.
If you want to trigger the action only for the image, you might have to add UITapGesture to the image view. Do not forget that image views have userInteractionEnabled set to false by default. There are two ways to communicate the tap event to the view controller that i can think of right now. Either by delegation or closure. The latter one requires less code.
Can this be done with the delegate method?
The reason I'm asking is because I have two buttons on the custom table cell. one deletes the cell and the other sends info from the table cell.m class into another view controller. How can I implement this properly?
Yes, you can setup a delegate relationship between a cell and the view controller, it follows the same structure and approach as a normal delegate relationship:
Create a protocol
Add a delegate property (weak)
Set the delegate when the cell is returned for display
nil the delegate when the cell is removed from display
Implement the delegate method(s) in the view controller
When you specify the delegate protocol methods, pass the pertinent information, something like:
- (void)tableCell:(UITableViewCell *)cell didTriggerButton:(UIButton *)sender;
with didTriggerButton set to an appropriate name for the purpose of the button. In this way the view controller can get the button if required and has access to the cell (so it can easily get the index path associated with it).
I have a custom CollectionViewCell class, I have then generated an amount of these inside of a CollectionView. I have then also added a modal segue when the ViewCells are touched. How would I get the id (or index path) of which cell was pressed when the modal segue is activated.
I saw on here that someone suggested I add into the ViewCell.m file the method
-(void)collectionView: (UICollectionView*)collectionView didSelectItemAtIndexPath: (NSIndexPath*)indexPath{
//get indexpath variable in here
}
But this method does not seem to be getting called. Can anyone help me with what method would need to be get called for when a CollectionViewCell has a modal segue to get the indexpath.
Thanks,
If the views you have added to your cells are handling the touch by firing a segue, then the collectionViewCell never has a chance to receive the touch.
If you want the collectionViewCell to handle it, make the subviews of your cell purely decorative by disabling their behavior to fire the segue. (for example, if they are buttons and "touchUpInside" fires the segue, then change them into views with no touch handling at all.).
Then the touch will be passed up through the view hierarchy until the CollectionViewCell handles it, which it does with the collectionView:didSelectItemAtIndexPath: method.
The method is a callback of the delegate class of the collection view object:
-(void)collectionView: (UICollectionView*)collectionView didSelectItemAtIndexPath: (NSIndexPath*)indexPath
So you should implement on the .m file of the delegate class of you collection view.
I have an undefined number of levels (depth) in my tableview, so i'd like to be able to create a segue between the view and itself so that i can call it as long as i have sub levels to discover. How can i do that ?
I've thought of directly using [self.navigationView pushViewController] when i need it, but i'd like the new controller to use the defined view in my SB.
Thanks,
EDIT: For now the only solution i've found is duplicating the VC, setting a segue between VC1 and VC2 called 'showNext', and a segue between VC1 and VC2 called the same way. Isn't there a better solution ?
If you're using dynamic cell prototypes, you obviously can do a segue from the table view cell to the controller without any problem.
When you make your segue, you end up with:
But let's imagine for a second that there's some reason that doesn't work for you, e.g. you could not have a segue from the cell (for example, you need to invoke segue from didSelectRowAtIndexPath, not upon selecting the cell). In this case, you couldn't use that previous technique.
There are a couple of options in this case:
As pointed out by Chris, if only supporting iOS 6 and above, use the above technique, but (a) make sure your didSelectRowAtIndexPath uses self for the sender and then have shouldPerformSegueWithIdentifier only allow the segue if the sender == self (thus when the sender is the table view cell, it will be canceled);
Perhaps even easier, just don't define a segue at all and have your didSelectRowAtIndexPath manually instantiateViewControllerWithIdentifier and then push/present that view controller as appropriate; or
You can use the following, kludgy work-around: In short, add a button to your view controller (drag it down to the bar at the bottom), where it won't show up on the view, but you can use its segues. So first, drag the rounded button to the controller's bar at the bottom of the scene:
Now you can make a segue from that button to your view controller:
And thus, you end up with the self-referential segue again:
You must give that segue an identifier, so you can invoke it programmatically via performSegueWithIdentifier, but it works. Not the most elegant of solutions, but I think it's better than having an extra scene on your storyboard.
None of these are ideal, but you have lots of options.
This process worked for me to do the exact same thing...
Set up your tableview in storyboard as usual. DO NOT give your prototype cell a Cell Identifier. Set up your segue as you did above, by dragging from the cell to the controller.
In your viewDidLoad register the cell class
//register the cell identifier as we are not loading form a storybard
[_aTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"CellID"];
In your cellForRowAtIndexPath set up your cell
static NSString *CellIdentifier = #"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Now you can use didSelectRowAtIndexPath and call performSegueWithIdentifier. the prepareForSegue will only be called once.
So basically, how can I push a UIViewController from a UITableView.
I have an array of contents on the TableView I need to tap inside the content and get the ViewController as result.
I tried making a - (IBAction)PushViewController:(id)sender but I can't reference the TableView.
Yes, i'm noob... ):
If you set a UITableViewDelegate for your table view, tableView:didSelectRowAtIndexPath: will get called when someone taps on a cell. At that point you can push another controller, optionally telling it what to display.