TableView cells do not communicate with their DetailView. - iphone

I have a TableViewController called SecondViewController. The cells' name is ok and everything works fine, but when it comes to loading the detailed view, which in my case is called ArticleViewController, it does not want to communicate with the detailed view's properties. So basically, if I want to change a label in the detailed view, it just does not work.
Here is the code:
SecondViewController.h
#interface SecondViewController : UITableViewController
{
NSMutableArray *json;
}
#end
SecondViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ArticleViewController *article = [self.storyboard instantiateViewControllerWithIdentifier:#"ArticleViewController"];
NSDictionary *info = [json objectAtIndex:indexPath.row];
NSLog(#"%#",[info objectForKey:#"username"]);
[article.usernameLabel setText:[info objectForKey:#"username"]];
[self.navigationController pushViewController:article animated:YES];
}
ArticleViewController.h
#import <UIKit/UIKit.h>
#interface ArticleViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *usernameLabel;
#property (weak, nonatomic) IBOutlet UILabel *articleTitle;
#end
ArticleViewController.m
--synthesizing properties--
I hooked the labels and the ArticleViewController up, but the label never changes.

I would guess that the article hadn't loaded its nib by the time you did article.usernameLabel setText:. So article.usernameLabel was still nil. You could force article to load its nib by doing [article view]. But OdNairy's advice is better.

Related

How to send data from UItextfields of one viewcontroller to new view controller? [duplicate]

I am a bit stuck on trying to pass data from two UITextfields on one viewcontroller to another viewcontroller. Basically I got the items below:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UITextfield *Textfield1;
IBOutlet UITextfield *Textfield2;
}
-(IBAction)GoNextView:(id)sender;
#end
ViewController.m
#interface ViewController ()
#end
#implementation ViewController
(IBAction)GoNextView:(id)sender {
SecondView *second = [[SecondView alloc] initWithNibName:nil bundle:nil];
[self presentViewController:second animated:YES completion:NULL];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
SecondView.h
#import <UIKit/UIKit.h>
#interface SecondView : UIViewController {
IBOutlet UILabel *ShowTextfield1;
IBOutlet UILabel *ShowTextfield2;
}
-(IBAction)GoBack:(id)sender;
#end
SecondView.m
#interface SecondView ()
#end
#implementation SecondView
- (IBAction)GoBack:(id)sender {
[self dismissViewControllerAnimated:YES completion:NULL];
}
What I want is, that when the button GoNextView is pressed it should pass the data in the UITextfield to the SecondView. And the go to the next page. The data should now be displayed in the two Labels on the SecondView. I've been struggling with this for many hours now and its killing me. I know I have to use some NSString and #property(nonatomic, retain) NSString *asdas. But I simply can't make it work. So based on the above code how do I pass data from the two UITextfield to the two labels on the next view?
Instead of navigating to the second view through a function, use Storyboard Segues. Create a storybaord application. To Create a segue you need a navigation view controller. You can do that by the following steps.
Select the first view controller and go to Editor -> Embed In -> Navigation Controller.
Then Ctrl+Click on the "GoNextView" button, and drag and drop in the SecondView.
You will get three options: push, model, custom. Click push then a segue will be created between these two views.
Click that segue and click the "Show the Attribute Inspector" on the right side property window. Now name it as "connector" or which ever name you prefer.
Now, in SecondView.h create two strings,
#property (nonatomic, retain) NSString *str1;
#property (nonatomic, retain) NSString *str2;
and synthesize them in SecondView.m.
Lets name your UITextFields as "text1" and "text2" which are in your ViewController. Go to the ViewController.h and add #import "SecondView.h"
In ViewController.m do the following,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"connector"])
{
ViewController *VC = [segue destinationViewController];
VC.str1 = text1.text;
VC.str2 = text2.text;
}
}
Now you can display these strings in your SecondView. In Secondview.m,
label.text = str1;
and it will be displayed.
Use NSUserDefaults or the normal synthesising common interface variables. For example,
NSUserDefaults
From sender's view controller,
NSString *text=textField1.text;
NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
[prefs setObject:text forKey:#"text1value"];
And you can get the value from any view controller as,
NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
NSString *received string= [prefs stringForKey:#"text1value"];
Normal assigners,
I believe you must be using performsegue to navigate view controllers. There is a delegate method called "prepareforsegue" and you can assign the textfield values into the interface variables. For example,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"seguename"]) {
destViewController *destViewController = segue.destinationViewController;
destViewController.name = #"some text";
}
}
In the receiver's view controller, getter variable is actually defined as,
In .h file, #property(nonatomic, strong) NSString *name;
In .m file, Don't forget to synthesis the variable after implementation
#implementation destViewController
#synthesize name;
Hope it helps!

DetailView shows only one entry of Tableview

I've got a Master-Detail Applicaton in Xcode with a TableView and a SearchDisplayController.
In the TableView I have got a NSArray with 10 entries.
If I use the Searchbar, the DetailView shows correctly the entry I clicked on.
But if I do not use the Searchbar and click in the TableView on an entry, the DetailView every time shows me the first entry of the TableView.
What can I do to fix it?
MasterViewController.m: http://i.imgur.com/ZS1Oe.png
MasterViewController.h:
#import <UIKit/UIKit.h>
#interface DPMasterViewController : UITableViewController
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#end
DetailViewController.m: http://i.imgur.com/AkVJ8.png
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface DPDetailViewController : UIViewController
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
Sorry that I use pictures, but I think it is easier for you to check. :)
I hope you can help me!
If anything is missing, just tell me.
EDIT:
In This Method after the else every time the indexPath.row = 0. I don't know how to fix it :(
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showDetail"]) {
DPDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
destViewController.detailItem = [searchItemList objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
destViewController.detailItem = [itemList objectAtIndex:indexPath.row];
}
}
}
It looks like you are not performing any actions when you click on a cell of the tableView that is not part of the searchDisplayController, so try to change your tableView:didSelectRowAtIndexPath: method to
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"showDetail" sender:self];
}

Access Delegate Data

Hello i'm trying to make a simple ios app with tabs and navigation .
in the delegate i have the following type:
BlogRss * _currentlySelectedBlogItem;
with this property:
#property (readwrite,retain) BlogRss * currentlySelectedBlogItem;
and i'm trying to get his data with two other classes, one is a table view with the data and the other will show the data;
in both classes i have declared the following:
#class NewsAppDelegate;
NewsAppDelegate * _appDelegate;
#property (nonatomic, retain) IBOutlet _NewsAppDelegate * appDelegate;
#synthesize appDelegate = _appDelegate;
ofter "touching" the cell in the table view i wrote this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[self appDelegate] setCurrentlySelectedBlogItem:[[[self rssParser]rssItems]objectAtIndex:indexPath.row]];
// Navigation logic may go here. Create and push another view controller.
// [[self appDelegate] loadNewsDetails];
NewsDetailViewController *detailViewController = [[NewsDetailViewController alloc] initWithNibName:#"NewsDetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
when i'm writing in the other class:
NSLog(#"%#",self.appDelegate.currentlySelectedBlogItem);
i'm getting null.
clearly i'm doing something wrong, but i don't know what...
The problem is likely that this line is returning null:
[[[self rssParser]rssItems]objectAtIndex:indexPath.row]
Code is easier to debug when you don't nest so many sentences.
You can access your delegate from anywhere because UIApplication is a singleton, you don't need to keep a reference as you do with self.appDelegate. Example:
(NewsAppDelegate *)[[UIApplication sharedApplication] delegate];
Or just do as Jennis suggest, who is a faster typer than me, and remove the IBOutlet. :P
When you do
NewsAppDelegate * _appDelegate;
#property (nonatomic, retain) IBOutlet _NewsAppDelegate * appDelegate;
#synthesize appDelegate = _appDelegate;
The result is the same if you skip the first line, because the runtime creates it for you.
See Question about #synthesize. And I guess _NewsAppDelegate is really NewsAppDelegate (no underscore).
Please do as follow.
//Your Header File
#import "YourAppDelegate.h"
#interface YourViewController : UIViewController
{
YourAppDelegate *appDelegate;
}
#property(nonatomic,retain) YourAppDelegate *appDelegate;
#end
//Your Implementation file
#implementation YourViewController
#synthesize appDelegate
- (void)viewDidLoad {
self.appDelegate = (YourAppDelegate*) [[UIApplication sharedApplication] delegate];
}
#end
After declaring as above you will have access of appDelegate anywhere in your view controller.
Hope it helps.

How can i display the data of the selected row from the tableview in the detail view in a splitview controller?

I've managed to read some values into a table view and display them in the Master View of a SplitViewController.
What I would like to do is to tap on a row of the Master View and display the details on the detailViewController but in a TableView.
When I tap on the row in the MasterView table, I can't seem to get the detail to populate the detailview TableView.
Any suggestions?
Thanks in advance.
Here's what you need to do:
Add an outlet to your master view controller which is a link to your detail view controller
Connect this outlet (either in Interface Builder or in code)
Add properties to your detail view for the values you're interested in displaying
in your implementation of tableView:didSelectRowAtIndexPath: retrieve the data for the selected row and set the corresponding properties in your detail view
Read this basic tutorial.
http://doronkatz.com/ipad-programming-tutorial-hello-world
Go through the sample code and see what you are doing wrong or missing
EDIT: its a tutorial on splitViewController.
may be this code is help for you
in table View .m file
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(self.dvController == nil){
DetailsViewController *viewControoler = [[DetailsViewController alloc]initWithNibName:#"detailsViewController" bundle:[NSBundle mainBundle]];
self.dvController = viewControoler;
[viewControoler release];
}
DocumentNavController *docObjNew = [appdelegate.noteArray objectAtIndex:indexPath.row];
[docObjNew hydrateDetailViewData];
//
dvcontroller.noteObj = docObjNew; //noteobj reference from in DetailsViewController.m file DocumentNavController *noteObj;
dvcontroller.currentindex = indexPath.row;
[self.navigationController pushViewController:self.dvController animated:YES];
self.dvController.title = [docObjNew noteTitle];
[self.dvController.noteTitelFiled setText:[docObjNew noteTitle]];
[self.dvController.notediscView setText:[docObjNew noteDisc]];
}
in table view .h file
#interface DocumentTableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *documenttableView;
evernoteAppDelegate *appdelegate;
UINavigationController *navControll;
DetailsViewController *dvcontroller;
DocumentNavController *docNavContro;
//NSIndexPath *selectIndexPath;
}
#property (nonatomic, retain)DetailsViewController *dvController;
#property (nonatomic, retain)DocumentNavController *docNavContro;
#property (nonatomic, retain)UITableView *documenttableView;
in DetailsViewController.h file
UITextField *noteTitelFiled;
UITextView *notediscView;
DocumentNavController *noteObj;
#property (nonatomic, retain)IBOutlet UITextField *noteTitelFiled;
#property (nonatomic, retain)IBOutlet UITextView *notediscView;
#property (nonatomic, retain)DocumentNavController *noteObj;

Calling a function from another UIViewController

I'm a beginner programmmer, this is for xcode - iPhone. although i made alot of my iPhone app but i seem to lack some understanding of how a simple communication might work.
Specially when I've got 2 ViewControllers.
And I wana call one function of a ViewController from another ViewController. Both are under a tabbarController. What I want to achieve is When I'm in ViewA, after tapping on a tableCell, I Should Invoke a method of ViewB and the NavigationBar of ViewB pushes to viewDetail.
The Following is the code i'm using
in ViewControllerA.h (where I'm calling a method)
#class ViewControllerB;
#interface SmartDDxViewController : UIViewController {
IBOutlet UITableView *tableView;
ViewControllerB *xViewController;
}
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, retain) ViewControllerB *xViewController;
And this is what I use to invoke it..ViewControllerA.m
ViewControllerB *ddViewController = [[ViewControllerB alloc] init];
self.xViewController = ddViewController;
[xViewController InitialiseDetailWithId:2 title:#"HEYA"];
Heres the InitialiseDetailWithId code: in ViewControllerB.m
-(void)InitialiseDetailWithId:(NSInteger)pkey title:(NSString *)tt{
NSLog(#"InitialiseDetailC=========================================");
AppDelegate *appDelegate = (Smart_DifferentialsAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate GetConditionDetailsWithId:pkey];
DDisViewController *viewController= [[DDisViewController alloc] initWithNibName:#"DetailView" bundle:nil];
viewController.title = tt;
[self.NavBar pushViewController:viewController animated:YES];
//[tt release];
[viewController release];
viewController = nil;
[self say:#"HEYA"]; //this is ALERTVIEW box that displays HEYA
}
I'm getting all information fine, and the alertview does get displayed. But when I chose that View in TabBar, its not pushed.
Do not use direct access between view controllers, instead use the delegate pattern. Define your controller like this:
#protocol ViewControllerAInitDelegate;
#interface ViewControllerA : UIViewController {
IBOutlet UITableView *tableView;
id<ViewControllerAInitDelegate> initDelegate;
}
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, assign) ViewControllerAInitDelegate *initDelegate;
#end
#protocol ViewControllerInitDelegate
-(void)initializeDetailWithId:(NSInteger)pkey title:(NSString)tt;
#end
So in
Now let your application delegate conform to the ViewControllerInitDelegate protocol. It should look something like this:
#interface AppDelegate : NSObject <UIApplicationDelegate, ViewControllerInitDelegate> {
IBOutlet UITabBarControler* tabBarController;
IBOutlet ViewControllerA* controllerA;
IBOutlet ViewControllerB* controllerB;
}
#end;
The AppDelegate should know about both ViewControllerA, and ViewControllerB, but neither of the view controller should know about each other. This way it will be much easier to debug and extend your app.
//current view controller index
int currentVCIndex = [self.navigationController.viewControllers indexOfObject:self.navigationController.topViewController];
//previous view controller (index -1)
AccountViewController *account = (AccountViewController *)[self.navigationController.viewControllers objectAtIndex:currentVCIndex - 1];
(access to anything you want)
account.property = object;
[account doSmthng];
In each of your view controllers, you might want to add a instance variable/property to keep track of the other view controller.
you might have for example:
#interface ThisViewController : UIViewController {
SomeViewController *sViewController;
// other instance variables
}
#property (nonatomic, retain) SomeViewController *sViewController;
This not only makes it easier to call methods from the other view controller and access its public properties, but it also allows you an easier way of flipping between the two (with or without animation).