Prepareforsegue navigationItem.title one behind - objective-c

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;
}
}

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

Trying to call a second table view with the items of de selected playlist in the first view

Maybe there's someone outthere who can help me fiure out my problem. I cant seem to display the playlistItems using cocoalibspotify. I have set up my playlistview and the first ableviewcontroller shows the playlist but when i try to call the items of the selected playlist I seem to get 0 numbersof row as my outputs show. the first view show how i pass the indexpath to the secondviewcontroller. the second script show my .h and .m files of the playlistitemsTavle view controller.
Overview.m - tableView with Playlists
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[playlistView deselectRowAtIndexPath:indexPath animated:NO];
playlistItemViewController *trailsController = [[playlistItemViewController alloc] initWithStyle:UITableViewStylePlain];
trailsController.currentPlaylist = [playlistArray objectAtIndex:indexPath.row];
//[[self navigationController] pushViewController:trailsController animated:YES];
[self getSongs];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showPlaylistItem"]) {
UITableViewCell *BasicCell = (UITableViewCell *) sender;
NSIndexPath *ip = [self.tableView indexPathForCell:BasicCell];
SPPlaylist *selectedPlaylist = [playlistArray objectAtIndex:ip.row];
playlistItemViewController *pivc = (playlistItemViewController *) segue.destinationViewController;
pivc.currentPlaylist = selectedPlaylist;
}
}
playlistitemsViewController.h -
#import <UIKit/UIKit.h>
#import "CocoaLibSpotify.h"
#import "Simple_PlayerAppDelegate.h"
#import "overViewController.h"
#interface playlistItemViewController : UITableViewController
{
UITableView *tableView;
}
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (strong, readwrite, nonatomic) SPPlaylist *currentPlaylist;
#end
playlistViewController.m - this should call the playlist items
#import "playlistItemViewController.h"
#interface playlistItemViewController ()
#end
#implementation playlistItemViewController {
}
#synthesize currentPlaylist;
#synthesize tableView;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"numberOfRowsInSection: %d",[[currentPlaylist items] count]);
return [[currentPlaylist items] count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SubtitleCell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [[[currentPlaylist items] objectAtIndex:indexPath.row] valueForKey:#"name"];
return cell;
if (indexPath.row == 0) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SubtitleCell"];
[[cell.backgroundView superview] bringSubviewToFront:cell.backgroundView];
cell.textLabel.text = #"";
}
else{
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"SubtitleCell"];
}
SPPlaylistItem * item = [[currentPlaylist items] objectAtIndex:[[currentPlaylist items]count] - indexPath.row];
cell.textLabel.text = [item.item name];
if (item.itemClass == [SPTrack class]) {
SPTrack * track = item.item;
cell.detailTextLabel.text = [track consolidatedArtists];
}
}
return cell;
}
#end
You need to wait for the playlist to load before the items are available.
Your playlist view controller needs to use SPAsyncLoading to load the playlist, something list this:
[SPAsyncLoading waitUntilLoaded:self.currentPlaylist timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notloadedItems) {
[self.tableView reloadData];
}];
Playlist loading can take a while, so make sure you put up some "loading" UI. You'll also need to load the visible tracks in a similar manner before their names will be available.

How to seque a subclass of UITableViewCell?

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;
}
}

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.

Can't find self.tableview after accidental delete

I accidentally deleted my firstviewcontroller.m file which is for a view that has a tableview. I then re-created my .m file the best I can remember and thought I had it all correct.
I'm now getting an error on the line
[self.tableview refresh];
saying self.tableview isn't found.
I can't seem to figure out what I missed. I don't want to overwhelm you guys with code so I'll try to just post the pertinent part.
#import "FirstViewController.h"
#import "Shared.h"
#import "Message.h"
#implementation FirstViewController
-(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] autorelease];
}
Message *msg = [[Shared sharedInstance].messages objectAtIndex:indexPath.row];
NSString *authorName = msg.authorName;
NSString *cellValue = authorName;
cell.textLabel.text = cellValue;
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
`return [[Shared sharedInstance].messages count];`
}
-(void) viewWillAppear:(BOOL)animated {
`[self.tableView reloadData];`
}
tableView is a property of UITableViewController. Double-check that you inherited FirstViewController from a UITableViewController, but not from UIViewController.