Passing Data Between View Controllers Not Working - objective-c

I am attempting to pass the label for a given selected cell to a different view controller...
ListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle: nil];
DetailViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"DetailVC"];
viewController.venueName = cell.textLabel;
[self.navigationController pushViewController:viewController animated:YES];
}
Here is my DetailViewController:
.h
#interface DetailViewController : UIViewController {
IBOutlet UILabel *venueName;
}
#property (nonatomic, strong) IBOutlet UILabel *venueName;
venueName never gets the data. In my .m I also synthesize the venueName.

This happens because your UILabel outlet is not connected at the time you set a string for it. I recommend you to create a string property to store the value and, in viewDidLoad in DetailViewController, you set the string to venueName.
Cheers!!

You need to modify the below like that for setting and getting the text:-
viewController.venueName.text = cell.textLabel.text;

So venueName, which is a pointer to a label, is made to point to an existing label that's part of a table cell. This is obviously wrong -- you don't mean to use the actual label from the table cell, but rather the text stored in it. Both the other answers here are correct: you surely mean to assign the text property of one label to that of the other, and the label that outlet viewController.venueName is connected to hasn't been created at the time this code executes.
The immediate thing you should do to fix your code is to assign the data in question (i.e. cell.textLabel.text) to a string property in the destination view controller. Have the -viewDidLoad or -viewWillAppear method in that controller set the text property of the venueLabel label. Either of those methods will be called after the view hierarchy is instantiated.

Related

UITableViewCell - registerNib subclass not finding nib as subview

In the viewDidLoad in my UITableView I am calling:
[self registerNib:[UINib nibWithNibName:#"MyCell" bundle:nil] forCellReuseIdentifier:#"MyCellRI"];
Then in the cellForRowAtIndexPath I have the following:
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCellRI"];
[cell setup:[items objectAtIndex:indexPath.row]];
Inside the setup method I have a look on [self subviews] to go through the subviews and assign content based on key/value but in this loop I find UITableViewCellContentView's but I do not see the my custom view defined in the NIB.
In the NIB I have assigned Files Owner & The custom class of my cell. The cell is showing I just can't find the NIB view in the subviews.
Please advise.
James
Iterating through subviews is hard work) Try to avoid it. it is not very good practice because it is not reliable. For instance if you decided to change your custom cell UI you will have to change method where you're iterating through subviews.
Try to do following:
Let's say that there is custom cell with UIImage and 3 strings (e.g. person's name, age and cell phone number)
Implement 3 functions in your custom cell to set this values as follows:
MyCustomCell.h
... .h file standart code and then at the end ...
#propert(nonatomic, strong) IBOutlet UIImageView *myImage;
#propert(nonatomic, strong) IBOutlet UILabel *myFirstLabel;
#propert(nonatomic, strong) IBOutlet UILabel *mySecondLabel;
#propert(nonatomic, strong) IBOutlet UILabel *myThirdLabel;
- (void)setUIimage:(UIImage *)_image;
- (void)setFirstString:(NSString *)_string;
- (void)setSecondString:(NSString *)_string;
- (void)setThirdString:(NSString *)_string;
MyCustomCell.m:
#synthesize myImageView, myFirstLabel, mySecondLabel, myThirdLabel;
- (void)setUIimage:(UIImage *)_image {
self.myImageView.image = _image;
}
- (void)setFirstString:(NSString *)_string {
self.myFirstLabel.text = _string;
}
- (void)setSecondString:(NSString *)_string {
self.mySecondLabel.text = _string;
}
- (void)setThirdString:(NSString *)_string {
self.myThirdLabel.text = _string;
}
and finaly in your tableView controller cellForRowAtIndexPath
[myCustomCell setUiImage:someImage];
[myCustomCell setFirstString:oneString];
[myCustomCell setSecondString:twoString];
[myCustomCell setThirdString:threeString];
Hope this approach will help you. Feel free to ask if you have some questions

Syntax error trying to set a property value

I want to pass a id from table view (TableViewController) to another view (ViewController) after tap a table cell. I have declared a storyboard ID "ViewController" for ViewController
Here is TableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
viewController.id=#"test";
[self.navigationController pushViewController:viewController animated:YES];
}
Here is ViewController.h
#property (nonatomic) NSString *id;
ViewController.m
- (void)viewDidLoad{
id= [[NSString alloc] init];
}
But the statement viewController.id=#"test"; occurred the syntax error.
id is a reserved word in Objective-C. Do not name any variable or property id. Rename it to something else.
Also, your viewController variable is declared as UIViewController. There is no id property in UIViewController. Change the type of viewController to the actual type it is (ViewController?).
ViewController *viewController = (ViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
Check the link below, covers these basics for beginners on how to pass data between UITableViewController to another view.
Storyboards Segue Tutorial: Pass Data Between View Controllers
By the way, i don't think you can use "id" as your property name.

UILabel text not changing, however xx.title is working

I have two view controller. In first view controller I have list of names. When I click on that, I want the same name to be displayed in second view controller.
I have below code.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// PropDetailViewController is second view controller
PropDetailViewController *prop = [self.storyboard instantiateViewControllerWithIdentifier:#"prop"];
ListOfProperty *propList = [propListFinal objectAtIndex:indexPath.row];
NSString *myText = [NSString stringWithFormat:#"%#", propList.addressOfFlat];
prop.detailLabel.text = myText;
prop.title = myText;
[self.navigationController pushViewController:prop animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
and in PropDetailViewController, I have #property (retain, nonatomic) IBOutlet UILabel *detailLabel;.
What I was expecting is when I click say Name 1, I will see Name 1 as text in UILabel and on the UINavigationBar too. However I only see Name 1 on navigation bar and not on UILabel.
It is not advisable to access an UIView item at that point in the program flow. When setting the value of prop.detailLabel.text the view may not have been loaded. When the view is loaded later then the UIView is updated with the default settings given in the XIB file in IB.
You should rather set an NSString property, lets say
#property (retain, nonatomic) NSString *propName;
assign it before pushing the view controller as you do. But use this property and not the UILable. And in PropDetailViewController in viewDidLoad do the following:
(void) viewDidLoad {
// call super viewDidLoad and all the works ...
self.detailLabel.text = propName;
}
Instead of viewDidLoad you could use viewWillAppear. Because viewDidLoad COULD be executed already when you assign the property's value.
If you want to be on the save side then invent a new init method where you hand over all the values that you want to be set upfront.
But I never did that in combination with storyboard (where you may use instantiate... rather than init...) and therefore I cannot give any advise out of the top of my head.
Another clean approach would be to stick with the propName property but to implement a custom setter -(void)setPropName:(NSString)propName; where you set the property (probably _propName if you autosynthesize) AND set the UILable text plus setting the UILable text within viewDidLoad.
Try this:
in .h
#property (retain, nonatomic) NSString *detailText;
in PropDetailViewController.m
Change line of code with
NSString *myText = [NSString stringWithFormat:#"%#", propList.addressOfFlat];
prop.detailText = myText;
prop.title = myText;
in ViewDidLoad:
[self.detailLabel setText:self.detailText];

Is it possible to create a static tableview in a storyboard and add it programmatically later? (iOS5, XCode 4)

I'm trying to create a couple of small, static tableviews and add them to a panel that I have which slides in and out. The panel is created programmatically so I can't lay the tableviews out inside it via storyboard, and anyway I'm not sure if this is possible anyhow: It seems the only way you can lay out static tableviews that work is in a tableviewcontroller, which takes up the whole screen.
If you can't tell I'm pretty new to iOS dev so if I'm not understanding some fundamental concepts here please feel free to explain.
Of course is possible. Here is how it can be done:
Drag a TableViewController to your storyboard.
Set its Size to Freeform, add an identifier and uncheck Resize View From NIB
Select the tableview and set its content to Static Cells. Design your cells.
Set its size
Now, wherever you need to instantiate it do it like this:
// I am using a UITableViewController as an example here
// you probably would like to set your actual controller subclass instead
UITableViewController *tableViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"staticTv"];
UITableView *tableView = tableViewController.tableView;
[self.view addSubview:tableView]; // Or add it to whatever view
Enjoy :)
A UITableViewController isn't necessary to provide the functionality you need to manage a UITableView. I think what you're looking for is the "Delegate" pattern. Any UIViewController can be assigned to be the delegate of the UITableView. For example, I have a "static" table that shows some options in an app I am working on:
#interface LBOptionsViewController : UIViewController <UITableViewDataSource,
UITableViewDelegate>
If you're creating your table views programmatically, you'll probably either be creating them in viewDidLoad or loadView (if you're creating the actual view yourself). After you've created your tableView, assign the delegates:
self.tableView.delegate = self;
self.tableView.dataSource = self;
Then your UIViewController subclass will receive the data delegate messages like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Not sure if this helps you. I have not played with Storyboards much yet.
EDIT: #Alladinian has the right answer! If you're using an property for the view controller make sure you allocate it if you need it to be called by other methods.
I've yet to find a usefully reason to use static table view cells over dynamic. Table views were pretty scary when I started iOS programming. I used sqlite in my first app YIKES.
So yeah, you should just import the UITableView Data Source and Delegate and follow up by adding the table view to your panel (assuming it's a uiview and you can add the table view as a subview).
Anyways in your ViewController.h include UITableViewDataSource and UITableViewDelegate.
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
Next, add properties for a UITableView and an NSMutableArray:
#property (strong, nonatomic) UITableView* tableView;
#property (strong, nonatomic) NSMutableArray* tableViewContents;
In your ViewController's .m:
#synthesize tableView;
#synthesize tableViewContents;
inside ViewDidLoad:
self.tableViewContents = [NSMutableArray arrayWithObjects:#"Cell 1",#"Cell 2",#"Cell 3",nil];
[self.tableView setDelegate:self]
[self.tableView setDatasource:self]
In the .m file:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.tableViewContents.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
index = row;
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
cell.textLabel.text = [tableViewContents objectAtIndex:row];
return cell;
}

table view selected index method not work (push)

there is a table view at my tab bar application' s firs tab. Then when click any row I want to do pushing secondviewController' s view. and there is label. The label's text must be selected row's text. I try this but not enter second tab :S How can I do this??? Also at secondViewController class have 3 view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
NSUInteger row2 = [indexPath row];
denemelik=row2;
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.enyakinfirma.text= [ws2.CustomerName objectAtIndex:[indexPath row]];
NSLog(#"kontrol2 %#",ws2.CustomerName);
[detailViewController release];
}
I assume that enyakinfirma is your UILabel that you want to populate with the text. You cannot assign text to the label before the label is actually created and loaded. And that happens later, after you push the new view controller.
Thus you need to create a separate #property in order to keep track of this text you need:
// SecondViewController.h
#interface SecondViewController {
NSString *customerName;
}
#property (nonatomic, retain) NSString *customerName;
#end
When you create the view controller you assign this property:
detailViewController.customerName = ...;
And in your view controller's viewDidLoad method you update the text.
-(void)viewDidLoad {
// ...
enyakinfirma.text = self.customerName;
}