How to seque a subclass of UITableViewCell? - objective-c

I've created a subclass of UITableViewCell. Until now, I've only been using cells which is "designed" in my storyboard where I can setup segues.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:segue sender:sender];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}
After I've created my subclass of UITableViewCell I'm no longer able to use the Storyboard to create segues for the custom cell, right? I've tried to create a cell in the storyboard and set its class to my custom class -- but then the cell is just blank when I run the App.
So instead I'm just alloc and init the custom cell in my tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WSTableViewCell";
WSTableViewCell *cell = (WSTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[WSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
WSObject *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell.titleLabel setText:item.title];
return cell;
}
Then in tableView:didSelectRowAtIndexPath I'm trying to creating the NewsViewController, setting the news item and push it to the navigationController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
News* news = [self.fetchedResultsController objectAtIndexPath:indexPath];
NewsViewController *newsViewController = [[NewsViewController alloc] init];
newsViewController.news = news;
[[self navigationController] pushViewController:newsViewController animated:YES];
}
But when I select a row my NewsViewController is not shown -- but instead I see a blank view with a black background. How can I deal with this? Is it possible to still use seques?

The problem I think is that you are using alloc-init to instantiate NewsViewController. That does not create your NewsViewController from storyboard. You have to use [UIStoryboard instantiateViewControllerWithIdentifier:(NSString *)identifier] to instantiate from storyboard.
However, I think the easier way is to call
[self performSegueWithIdentifier:#"showNews" sender:indexPath]
in your didSelectRowAtIndexPath. You have to change your prepareForSegue... a little bit.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = (NSIndexPath *)sender;
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}

Related

prepareForSegue after didSelectRowAtIndexPath?

Can we make a rank like prepareForSegue after didSelectRowAtIndexPath?
My NSLog sends a good sentence, this NSLog is that I want (in didSelectRowAtIndexPath but assign AFTER to my NSLog in prepareForSegue) I would like the NSLog in prepareForSegue sends the same sentence that didSelectRowAtIndexPath.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
self.cellSelected = cell.textLabel.text;
NSLog(#"la : %#", self.cellSelected);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showPhotoView"]) {
NSLog(#"ou %#", self.cellSelected);
PhotoViewController *viewController = (PhotoViewController *)segue.destinationViewController;
viewController.cellSelected = self.cellSelected;
}
}
If you use a segue that originates from a UITableViewCell the sender parameter will actually contain the UITableViewCell that was selected. So you could just use the sender parameter to get the data you need.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showPhotoView"]) {
UITableViewCell *cell = sender;
PhotoViewController *viewController = (PhotoViewController *)segue.destinationViewController;
viewController.cellSelected = cell;
}
}
Yes you can ! You need just to fix some things
Here is an example i used
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"friends2" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"friends2"]) {
NSString * object = nil;
NSIndexPath *indexPath2 = nil;
if (self.searchDisplayController.isActive) {
indexPath2 = [[ self.searchDisplayController searchResultsTableView]indexPathForSelectedRow];
object = self.results[indexPath2.row];
NSLog(#"is active : %#", object.self);
} else
{
indexPath2 = [self.tableView indexPathForSelectedRow];
object = sortedArray.self[indexPath2.row];
NSLog(#"is not active : %#", object.self);
}
with didSelect.. i just made the segue, and with performSegue you do what you want to do

UICollectionViewCell is not showing DetailView when tapped

I implemented a CollectionView with ImageViews in the cells. I want a DetailViewController to appear when the cell is tapped. I set the User Interaction Enabled in the Interface Builder for the ImageView and the Cell. What am I making wrong? I have this code in the ViewController:
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
return 9;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
PhotosCell *cell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
// load the image for this cell
NSString *imageToLoad = [NSString stringWithFormat:#"%d.jpg", indexPath.row +1];
// NSLog(imageToLoad);
cell.imageView.image = [UIImage imageNamed:imageToLoad];
return cell;
}
// the user tapped a collection item, load and set the image on the detail view controller
//
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// NSLog(#"inside!");
if ([[segue identifier] isEqualToString:#"showDetail"])
{
NSIndexPath *selectedIndexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
// load the image, to prevent it from being cached we use 'initWithContentsOfFile'
NSString *imageNameToLoad = [NSString stringWithFormat:#"%d_full", selectedIndexPath.row+1];
NSString *pathToImage = [[NSBundle mainBundle] pathForResource:imageNameToLoad ofType:#".jpg"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage];
PhotoDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.myImage = image;
}
}
But the method "prepareForSegue" is not being called when the cell is tapped...
implement collectionview delegate method
collectionView:didSelectItemAtIndexPath:
there call
[self performSegueWithIdentifier:#"showDetail" sender:self];

table view use customized cell file and how ot use segue

I user Master-Detail created a project. On the MasterViewController, the table cell i use a MasterCell.h and MasterCell.m to build my customized cell, so my code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MasterCell *cell = (MasterCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[MasterCell alloc] initWithFrame:CGRectZero];
NSString *value = [[myContacts objectAtIndex:indexPath.row] valueForKey:#"Name"];
cell.nameContentLabel.text = [NSString stringWithFormat:#"%#", value];
value = [[myContacts objectAtIndex:indexPath.row] valueForKey:#"Tele"];
cell.teleContentLabel.text=[NSString stringWithFormat:#"%#", value];
value = [[myContacts objectAtIndex:indexPath.row] valueForKey:#"Image"];
cell.myImageView.image = [[UIImage alloc] initWithContentsOfFile:value];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
And whan i want click the cell and push the DetailViewController, so my stroyboard is use the origin creat segue, but it didn't work, i think the segue is not my MasterCell, and i had try to change the storyboard cell custom Class, and it was't not success.How do I do? Thanks.
In your storyboard you should create segue not from cell, but from entire UITableViewController and set some identifier, for example "MySegue" and style is "Push".
Then in your tableViewController you should add
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"MySegue" sender:self];
}
and
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"MySegue"]){
//do your stuff
}
}

Prepareforsegue navigationItem.title one behind

I'm still relative new to object c, so please bear over with me if this is a rookie question. I'm trying to set the title of my navigationcontroller with the corresponding object information. I'm using prepareforsegue for it, but the first time is segue to the new controller, the title is blank. If i try again, it shows up, but if i pressed something else, it shows the title of the things i pressed the time before. I have embedded my code below.
//.h
#import <UIKit/UIKit.h>
#interface STATableViewController : UITableViewController
#property(strong,nonatomic)NSArray *listOfExercises;
#property(weak,nonatomic)NSString *navTitle;
#end
//.m
#import "STATableViewController.h"
#import "ExercisesViewController.h"
#implementation STATableViewController
#synthesize listOfExercises = _listOfExercises, navTitle = _navTitle;
- (void)viewDidLoad
{
[super viewDidLoad];
_listOfExercises = [NSArray arrayWithObjects:#"Raketstart",#"SpeedBåd",#"Træstamme",nil];
self.navigationItem.title = #"Exercises";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [_listOfExercises count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *cellValue = [_listOfExercises objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_navTitle = [_listOfExercises objectAtIndex:indexPath.row];
//NSLog(_navTitle);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"toExercise"])
{
ExercisesViewController *foo = [segue destinationViewController];
foo.navigationItem.title= _navTitle;
}
}
#end
This is happening because prepareForSegue:sender: is being called before tableView didSelectRowAtIndexPath:. So you are always setting your navigationItem's title before you are setting your _navTitle property with the value you want.
Instead of getting the title in didSelectRowAtIndex path, do it in your prepareForSegue like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"toExercise"])
{
// "sender" is the table cell that was selected
UITableViewCell *cell = (UITableViewCell*)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSString *title= [_listOfExercises objectAtIndex:indexPath.row];
ExercisesViewController *foo = [segue destinationViewController];
foo.navigationItem.title = title;
}
}

prepareForSeque doesn't fire

I have UIViewController with a button, button opens a firstTableViewController -> tabViewController (with 3 tabs) -> one of the tabs has a secondTableViewController -> UIViewController.
Everything is in storyboard.
In firstTableViewController the prepareForSeque works fine. I don't even have didSelectRow...
But on secondTableViewController the prepareForSeque doesn't fire. So I added didSelectRowAtIndexPath as follows. But still the prepareForSegue doesn't work.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"ShowComment" sender:self];
}
-(void) performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
[self prepareForSegue:self.storyboard sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//When a row is selected, the segue creates the detail view controller as the destination.
//Set the detail view controller's detail item to the item associated with the selected row.
NSLog(#"test");
if ([[segue identifier] isEqualToString:#"ShowComment"]) {
}
}
I found the issue. I did not have an identifier for the cell. Selected the Prototype Cells in the storyboard, in the attributes inspector -> identifier entered 'Cell1'.
In the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell1";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
Note *note = [notes objectAtIndex:indexPath.row];
cell.textLabel.text = note.title;
return cell;
}
voila, it worked.