Xcode - didSelectRowAtIndexPath doesn't run - ios

i have this simple code in the didSelectRowAtIndexPath method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
NSString *selected = #"test";
NSLog(#"You choose: %#", selected);
}
This is my ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
IBOutlet UITableView *tableData;
}
#end
When i run the App, the TableView display all data, but then i cliked in a cell the method above doesn't run (?)

Have you set the delegate for the tableview in your storyboard, select your table view right click and drag to the view controller and you should see the option to set dataSource delegate and tableviewdelegate - I forget the exact names.

e.g.: thats part of my code, but should show you what you need to do. You need to hand over the data somewhere.
NSDictionary *oneDict = [_noteBookArray objectAtIndex:indexPath.row];
NSString *touchString = [oneDict objectForKey:#"value"];
NSString *dateString = [oneDict objectForKey:#"timestamp"];
//call the method who does it
[_noteBookViewController setContentAndTimeStampWith:touchString and:dateString];
//set the present View Controller active (the controller who contains the values)
[self presentViewController:_noteBookViewController animated:YES completion:nil];
method from the notebookviewcontroller
- (void)setContentAndTimeStampWith:(NSString *)contentString and:(NSString *)timeStampString
{_textInputView.text = contentString;
_timeStampString = timeStampString;}
got it?

Related

Pass data back to Viewcontroller from tableview

I have ViewController and TableViewController. In ViewController i have a 2 buttons and 2 textfields, when button1 is clicked it will navigate to UITableView with static data like (Apple, Samsung, Blackberry, Windows),and button2 is clicked it will navigate to UITableView static data (Doctor, Engineer,Businessman, Employee)when i select any of the row it should be displayed in the textfield1 of button1 clicked and textField2 of button2 clicked ViewController. below is what i have tried as am learning, i don't know wheather it is correct or not.
CustomerVC.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)button1Click:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *txtField1;
- (IBAction)button2Click:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *txtField2;
CustomerTableVC.h
#import <UIKit/UIKit.h>
#interface DetailsViewController : UITableViewController
#end
CustomerTableVC.m
#import "DetailsViewController.h"
#interface DetailsViewController ()
{
NSArray *array1,*array2;
}
#end
#implementation FamilyDetailsViewController
- (void)viewDidLoad {
[super viewDidLoad];
array1=[[NSArray alloc]initWithObjects:#"Apple",#"Samsung",#"Blackberry",#"Windows", nil];
array2=[[NSArray alloc]initWithObjects:#"Doctor",#"Engineer",#"Businessman",#"Employee", nil];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array1 count];
return [array2 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];
}
cell.textLabel.text=[arrqy1 objectAtIndex:indexPath.row];
cell.textLabel.text=[arrqy2 objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.navigationController popViewControllerAnimated:YES];
}
You should use Unwind segue to pass data back from your tableview controller..
Steps to follow:
Suppose A & B are two controllers and you first navigated from A to B with some data. And now you want to POP from B to A with some data.
Unwind Segues is the best and recommended way to do this.
Here are the steps.
Open A.m
define following method
#IBAction func unwindSegueFromBtoA(segue: UIStoryNoardSegue) {
}
open storyboard
Select B ViewController and click on ViewController outlet. press control key and drag to 'Exit' outlet and leave mouse here. In below image, selected icon is ViewController outlet and the last one with Exit sign is Exit Outlet.
You will see 'unwindSegueFromBtoA' method in a popup . Select this method .
Now you will see a segue in your view controler hierarchy in left side. You will see your created segue near StoryBoard Entry Piont in following Image.
Select this and set an identifier to it. (suggest to set the same name as method - unwindSegueFromBtoA)
Open B.m . Now, wherever you want to pop to A. use
self.performSegueWithIdentifier("unwindSegueFromBtoA", sender: dataToSend)
Now when you will pop to 'A', 'unwindSegueFromBtoA' method will be called. In unwindSegueFromBtoA of 'A' you can access any object of 'B'.
That's it..!
Try using delegate.
1. Declare delegate on Tableview controller's.
In Custom Vc
Declare FamilyViewController.delegate = self;
self.view presentviewcontroller = familyviewController;
Define the delegate function (eg. detailsselected())
Inside the detailsSelected dismissViewController.
In FailyDetailsViewController:
Inside the didselectRowAtIndexPath : call the "detailsSelected" function and pass the selected values.

tableView didSelectRowAtIndexPath doesn't work properly on iOS 7. Why?

In first place I would like to say that I'm only making this question, because I would like to understand what is happening.
I opened an old Xcode project (a very simple one) in a fresh installation on Xcode5.
When I realize that it doesn't work on iOS 7. Why? Don't know..
I saw some other questions, didn't get any useful answer, so I made a simple test.
In the UITableViewController all works fine except on didSelectRowAtIndexPath
Check it out
RootViewController.h:
#interface RootViewController : UITableViewController
#property (strong, nonatomic) NSMutableArray *items;
#end
RootViewController.m
In viewDidLoad I init the array (with some strings).
Implement the dataSource and delegate methods (and yes I set the delegate and dataSource to the tableView)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_items 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];
}
// Configure the cell...
cell.textLabel.text = [_items objectAtIndex:indexPath.row];
return cell;
}
The problem is here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:NO];
detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
}
DetailViewController is a simple UIViewController:
(yes, I set the IBOutlet on nib file)
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
#end
The problem is that this doesn't work on iOS7, the label in DetailViewController doesn't get updated. I try to set the label text before and after of pushViewController.
This works on all previous versions of iOS.
Why is not working on iOS 7 ??
The only way I get this working is, like I saw on this other question:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
dispatch_async(dispatch_get_main_queue(), ^{
detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
});
}
Can somebody help me out to understand what is going on here??
Thanks!
_
EDIT
it also works like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
if (detailViewController.view) {
// do notihing
}
detailViewController.detailLabel.text = [_items objectAtIndex:indexPath.row];
}
At the time when you set the value of the UILabel, the view has not yet been loaded, so if you check in debug, you'll probably find detailLabel is nil.
Why not pass the value in a custom init method? e.g.
- (id)initWithDetails:(NSString *)detailsText;
Then in viewDidLoad, assign the value?
According to your edit, in answer to your question as to why it is working:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TestViewController *test = [[testViewController alloc] init];
NSLog(#"Before: %#", test.label);
if(test.view){}
NSLog(#"After: %#", test.label);
[[test label] setText:#"My Test"];
[self.navigationController pushViewController:test animated:YES];
}
I have mocked up your scenario, if you access 'view' on a ViewController, it will call viewDidLoad if the view does not exist. So your UILabel now becomes set. Here is the output from the console.
2013-10-11 16:21:04.555 test[87625:11303] Before: (null)
2013-10-11 16:21:04.559 test[87625:11303] After: <UILabel: 0x75736b0; frame = (148 157; 42 21); text = 'Label'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7573740>>
I recommend using a custom init method, rather than this approach - this above example is a hack. Use something like this E.g.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
testViewController *test = [[testViewController alloc] initWithText:#"My Test"];
[self.navigationController pushViewController:test animated:YES];
}
If you do not wish to use a custom initialiser, I suggest a public property on your DetailViewController of type NSString. Assign that using your approach after init is called. Then within DetailViewController, in viewDidLoad, or appear, set the IBOutlet to the value of the property containing the NSString.
Its not getting updated because you are making writing
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
You are making the UILabel as weak property. You must make it strong property.
#property (strong, nonatomic) IBOutlet UILabel *detailLabel;
As you are making your property weak so its getting destroyed.
To know more about weak and strong propertied you can refer
Differences between strong and weak in Objective-C

How to add UITableView to existing view

How do I add a UITableView to an existing view?
I have added the control via interface builder, and added the correct delegates to the host view controller (including adding the table cell functions to the .m file)
But nothing gets called and nothing gets populated, the cellForRowAtIndexPath function, for example, never gets called.
in .h file
#interface GameViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *friendsScoresView;
in .m file
init {
_friendsScoresView.delegate = self;
_friendsScoresView.dataSource = self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return number of rows
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyBasicCell"];
//NSMutableArray *nearbyScores = gclb->nearbyScores;
GCLeaderboardScore *playerScore = [gclb->nearbyScores objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%f",playerScore->score ];
cell.imageView.image = playerScore->photo;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// handle table view selection
}
What am I missing? Also how do I tell the table to update / refresh its contents?
If you added the UITableViewController in IB then click on the outlets tab on the right and connect the DataSource and Delegate in IB. If you want to do it in code, then create an IBOutlet variable for your table and set the delegate and datasource property on your variable. Also, you can't do it on init on the UIViewController as the NIB has not yet been loaded. Do it on viewDidLoad.

Changing title in UINavigationBar when a row from UITableView is touched

Ok, so I have tried this a lot of different ways...
At the moment I have placed the UINavigationBar with the IB. Then declared it with IBOutlet.
From there I can't seem to change the title no matter what i try. Even just in ViewDidLoad.
Also, I dont need to assign the delegate of the navbar do i?
Here is my code:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController < UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArrayOne;
NSArray *myArrayTwo;
UITextView *myTextView;
UINavigationBar *myNavBar;
}
#property (nonatomic, retain) NSArray *myArrayOne;
#property (nonatomic, retain) NSArray *myArrayTwo;
#property (nonatomic, retain) IBOutlet UITextView *myTextView;
#property (nonatomic, retain) IBOutlet UINavigationBar *myNavBar;
#end
and:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
//Synthesising anything with a property call in the .h file.
#synthesize myArrayOne;
#synthesize myArrayTwo;
#synthesize myTextView;
#synthesize myNavBar;
- (void)viewDidLoad
{
//declaring and instantiating datapaths and also
// reading into arrays from plist.
NSString *datapath1 = [[NSBundle mainBundle] pathForResource:#"myListOne" ofType:#"plist"];
NSString *datapath2 = [[NSBundle mainBundle] pathForResource:#"myListTwo" ofType:#"plist"];
myArrayOne = [[NSArray alloc] initWithContentsOfFile:datapath1];
myArrayTwo = [[NSArray alloc] initWithContentsOfFile:datapath2];
self.navigationItem.title = #"Hi";
[super viewDidLoad];
}
#pragma mark - TableView Delegate stuff
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//myNavBar.title = [myArrayOne objectAtIndex:indexPath.row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - TableView Datasource stuff
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//returns amount of items inside myArrayOne as amount of rows
return [myArrayOne count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *myCell = nil;
myCell = [tableView dequeueReusableCellWithIdentifier:#"myReuseCell"];
if (myCell == nil)
{
myCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myReuseCell"];
}
myCell.textLabel.text = [myArrayOne objectAtIndex:indexPath.row];
return myCell;
}
#end
the actual code to change the title is just one way i have tried...
Any other way? And do I need to link the navigationbar in the IB with anything?
If you have a navigation bar without a navigation controller, you have to give it a stack (in your case, a stack of one) navigation items.
In viewDidLoad of your view controller, add your view controller's navigation item to the stack:
self.myNavBar.items = #[self.navigationItem];
Now you can set the title like so:
self.navigationItem.title = #"Hello";
and it will appear in your navigation bar.
The solution above by jrturton works fine UNLESS you also have a UIBarButtonItem (e.g. a "Done" button) in the UINavigationBar. In that case, the proposed solution causes the UIBarButtonItem to disappear.
Here's how to do it in a way that lets you change the UINavigationBar title but also preserve the UIBarButtonItem:
Add IBOutlet UINavigationItem *myNavigationItem; to your code.
In IB, in the outline view (not the storyboard view), right click the containing UIViewController and drag to the UINavigationItem that was automatically created by IB inside the UINavigationBar and connect to myNavigationItem.
Back in your code, add self.myNavigationItem.title = #"Hello";
I think you need to have a navigationController instead why don't you check this link:
create navigation bar for tableView programmatically in objective-C
and if you already have a navigation controller in your app delegate, then you should remove the IBoutlet you've created then use:
self.navigationItem.title = #"Hi";
for this will be referring the navigationController in your app delegate.

How to pass latitude value to next view in iphone?

I have got response from services and I have got latitude value and I copied into an array.
Now I want to pass the array when I click the next views row.
I passed places earlier. In second view UITableViewController is there if I click the particular row then it should be printed the rows text value and particular text's latitude value.....?
Is this possible...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *myText=[places objectAtIndex:indexPath.row];
NSLog(#"his is selected lattidude value:%#",myText);}
Here I am printing the row's text with this I need to print the latitude value of each one....please help me.
There are lot many way to pass data from one view to other view.
Best for you is like:
Just create one variable in your second view controller.
When you push navigation from current page just before assign your value to that variable.
now you can easily use that value in your second view.
in your SecondViewController in .h file just
#interface SecondViewController : UIViewController{
NSString *strLatLong;
}
#property (nonatomic, retain) NSString *strLatLong;
#end
and in .m file just synthesize it like bellow..
#synthesize *strLatLong
and in your FirstViewController class just push with bellow code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *myText=[places objectAtIndex:indexPath.row];
NSLog(#"his is selected lattidude value:%#",myText);
SecondViewController *objSecondView = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
objSecondView.strLatLong = myText;
[objSecondView.strLatLong retain];
[self.navigationController pushViewController:objSecondView animated:YES];
[objSecondView release];
}
i hope this help you...
Create #property in second viewcontroller class .h file
#property (nonatomic ) NSString *StrName;
#synthesize in second viewcontroller class .m file
#synthesize StrName;
after that in your current viewcontroller class
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//NSString *myText=[places objectAtIndex:indexPath.row];
secondviewcontroller *ss=[[secondviewcontroller alloc]initWithNibName:#"secondviewcontroller" bundle:nil];
ss.StrName=[places objectAtIndex:indexPath.row];
[self presentModalViewController:ss animated:YES];
}
you must create a variable in second class and define his property and on first class you use this property to send one value to next class you sed value like this
in first class you create a variable with property like this
#property(nonatomic ,strong) NSString *str;
and in first class when you create the object of second class then you send the value like this
SecondClass *secondClass=[[SecondClass alloc]init];
secondClass.str=#"value is here";
in this method you send value to next class
i hope you understand ;-)

Resources