I have a UIPopoverController that has a UITableView that is populated. I am trying to pass the information from the popovercontroller to the superview. The tableview that is placed in the popovercontroller is receiving the information with the didSelectRow method but the information is not transferring to the textView placed in the superView.
Below is the code I use to try and place the selected user in the textview and underneath that is the Superview code where I try to take the string and place it into the actual field when the index is clicked. I know my issue is I am not telling my superView that the row was touched and to send that information into the field but I have searched and con not find a good explanation on how to attempt this.
If anyone has any suggestions that would be great!
thanks
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
if (indexPath){
NSString *selectedUser = [(Tweet*)[Friend objectAtIndex:indexPath.row]
followingScreenName];
TwitterFollowersTimline *textBox = [[TwitterFollowersTimline alloc]
initWithNibName:#"TwitterFollowersTimeline" bundle:[NSBundle mainBundle]];
textBox.selectedFriend = selectedUser;
NSLog(#"%#", selectedUser);
[textBox release];
textBox = nil;
}
}
In my SuperView
selectedFriend = [[NSString alloc] init];
creatTweetText.text = [NSString stringWithFormat:#"#%#", selectedFriend];
In order to pass information from the View Controller of the popover you're going to want to set up a delegate. Here's a link to Apple's documentation and also a good guide example.
https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
Essentially when you create the View Controller that houses the methods for your table view, you'll want to give it a delegate. Then once a cell is selected in your table view, you'll be able to send a call to your delegate with any information you need.
Related
My setup is using a storyboard in which I create a login, then a home screen in which the user can press a button to display their messages.
These are displayed in a table which is instantiated programmatically.
From this table I then want to press a row to go into detail about that row, but when i do this the view displayed is blank but all methods associated with the class are being fired (view did load, and so on).
I have literally tried 10 different ways from different solutions others had had suggested on their questions but nothing works.
Code to make new view and push it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
messageDetail *messageDetailView = [[messageDetail alloc]initWithNibName:nil bundle:nil];
messageDetailView.message = [entityObjects objectAtIndex:indexPath.row];
[self.navigationController pushViewController:messageDetailView animated:YES];
}
ViewDidLoad of DetailView:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Message Detail:\n%#",message);
messageTitle.text = message.message_title;
messageBody.text = message.message_xml;
}
I have tried using a segueIdentifier route and then intercepting the prepareSegue: to add data to the new view, but as the tableView is created programmatically there is no segue.
I have tried instantiating the view from storyboard via:
messageDetailView = [self.storyboard instantiateViewControllerWithIdentifier:#"MDV"];
But the app crashes as there is no view with identifier, even though i set the identifiers.
You send nil as nib name, if you do not have a nib file do not allocate the message detail view with initWithNibName function.
Use raw init or initWithFrame. Whichever works for you.
Good luck
I basically did the same thing with this code here. Hope this helps
Detail_View *next=[[Detail_View alloc] initWithNibName:#"Detail_View" bundle:nil];
//These are just values that I needed to set before going to the next page.
//You can use this if you want to pass over the value of your table row
//otherwise ignore this
next.htmlContents= [[storage_array objectAtIndex:indexPath.row]objectForKey:#"title"];
next.titleText=[[storage_array objectAtIndex:indexPath.row] objectForKey:#"title"];
[self.navigationController pushViewController:next animated:YES];
I have a error in my script, it doesn't works. but I don't know how to change it.
I'm using 2 views, I'd like to use if/else for changing the text on the favoriteColorLabel on the second view from the first.
If someone know the problem, please help me.
Th
My code :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row==1) {
DetailVC.favoriteColorLabel=#"Bonjour";
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
dvController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:dvController animated:YES];
}
}
Thanks.
I think the error is on this line:
DetailVC.favoriteColorLabel=#"Bonjour";
It is most likely you actually want to set the text attribute of your label like this:
DetailVC.favoriteColorLabel.text=#"Bonjour";
This is because the text attribute is the text displayed by the label onscreen. You were setting the actual UILabel object to an NSString literal, which is probably not what you wanted to do.
You are setting Text to a label Thats why you are getting error in your code.
You need to do it as like this:
labelname.text = #"String";
Then your issue will resolve.
Hope it works.
I would consider setting a label in the second view from a method in the first bad design and error prone.
What I would do, is give your detail view controller a property that is an NSString *. After you create the detail view controller from your first controller, you pass the text #"Bonjour" to that property (by using its setter method) and then you can present the detail view controller. This second view controller can look at the value of its string and set the label accordingly.
The detail view controller is there to manage its own views, it should not need you first view controller to manage what's onscreen.
How would I be able to pass the name of a table cell that is clicked in a Master View Controller to a Detailed View Controller. I would like it to be used later in my detailed view right now though I would like to use this data for the detailed view's navigation item title by means of self.navigationItem.title =. Can anyone please provide basic code to how to make this happen?
Your going to want to use the didselectrowatindexpath method. Something like this, initialize the new view and set the title:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *myDetViewCont = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
NSInteger row = indexPath.row;
NSString *title = [ListOfItems objectAtIndex:row];
myDetViewCont.navigationItem.title = title;
[self.navigationController pushViewController:myDetViewCont animated:YES];
}
If you only want to set the navigation title, you can just set it before you push the detailViewController in navigation controllers' stack.
detailViewController.title = #"whatever you want";
If you do need the name of the cell for other places, then make a NSString property in DetailViewController, and set it before pushing.
The easy way is to create a property in the detailed view controller and set it to the title. Then you can use in the ViewDidLoad to set the title.
psuedo code:
create detailed view controller
set property
push it on the navigation bar
grab property in ViewDidLoad
im my app that im tring to build, i want to have a table view, where you select a row e.g email address. the view pushes to a simple page with a uitextField, when you hit the save button it pops the view controller back to the initial page, where the user can select the next field.
the issue that i am having is passing the information entered in the textfile back to the first view controller. this should be really simple, but anything i try just does not work
what is the best way to go around this.
thanks
You are probably thinking about the problem backwards. In an MVC system like Cocoa, the job of View Controllers is to manage views, not data. Create a model object to hold the data you're updating. When you create a view controller, pass the model object to it. It may update the model with changes the user makes. It should not worry about who called it, or who it returns to. It should just update the model object, and other interested parties should read the model object. As an example:
SettingsViewController would have a model object called Settings
When you dive into a detail view controller like EmailViewController, you pass the settings to it like emailViewController.settings = self.settings before presenting it.
When the user makes changes, just update the object like self.settings.emailAddress = ...
This separates your view logic from your model logic, which is a key features of Cocoa patterns. If you fight this pattern, you're going to often find yourself thinking "it sure is hard to get there from here."
You can either use a delegate method or, even simpler, just define an instance variable NSString *textEntry in the first view controller that can be set (property/synthesize) and then access that view controller from the stack.
For example, in the pushed view, do something like:
FirstViewController *firstViewController = [[[self navigationController] viewControllers] objectAtIndex:0];
[firstViewController setTextEntry:[textfield text]];
The easiest way I found to do this is using NSNotificationCenter.
In the ViewController with the TableView:
- (void)updateRowValue:(NSNotification *)notification{
NSDictionary *valuesDictionary = [[NSDictionary alloc] initWithDictionary: [notification userInfo] copyItems:NO];
NSString *newString = [valuesDictionary objectForKey:#"StringVal"]
}
This is the method called when row is selected
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TextFieldViewController *tfvc = [[TextFieldViewController alloc] init];
[tfvc setPostNotificationString:#"updateRowValue"];
[self.navigationController pushViewController:tfvc animated:YES];
}
Now in the viewController with the textField, when you press the button to return to the previous viewController call this:
- (IBAction)saveButtonPressed{
NSArray *valuesArray = [[NSArray alloc] initWithObjects:textField.text,nil];
NSArray *keyArray = [[NSArray alloc] initWithObjects:#"StringVal",nil];
NSDictionary *dictionary = [[[NSDictionary alloc] initWithObjects:valuesArray forKeys:keyArray] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:[self postNotificationString] object:self userInfo:dictionary];
[[self navigationController] popViewControllerAnimated:YES];
}
I have a TableView setup as my "root view controller" and a detail view controller called "DetailController" to allow me to display the detail view for what the user selects in the main table view. The navigation is working correctly - when I select a row in my table the screen slides to the left and I'm presented with my detail view, but I can't update the detail view's UILabel text properties. It's like it is just ignoring my UILable set property methods (see code below) as it isn't giving me any errors or warnings.
I've tested that I do have the values I need when I hit the "tableView:didSelectRowAtIndexPath:" method, but for some reason I can't seem to update the detail view's UILabels' text properties. Using NSLog's I can see that I am getting the values and passing them correctly to the UILabels. However the detail view isn't showing the passed values in its UILabels.
The strange thing is that I CAN set the detail view's title property correctly, just not the UILabel properties, which is very confusing!
Here's my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
if (self.detailView == nil) {
DetailController *detail = [[DetailController alloc] initWithNibName:#"DetailController" bundle:nil];
self.detailView = detail;
[detail release];
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[theList getItem:cell.textLabel.text]];
[self.detailView.theID setText:#"LOOK AT ME NOW!"];
self.detailView.thePrice.text = [[dict objectForKey:#"PRICE"] stringValue];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:self.detailView animated:YES];
NSString *newTitle = [[NSString alloc] initWithString: #"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
}
Thanks for any help on this! I love this community - you guys are awesome!
I Found An Answer! I think...
After much trial and error I was able to figure out a solution, but the solution doesn't entirely make sense to me and still leaves me with questions.
Siegfried suggested that I move my "pushViewController" message to the end of the method so that the last six lines of my code were changed to:
// Pass the selected object to the new view controller.
NSString *newTitle = [[NSString alloc] initWithString: #"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
[self.navigationController pushViewController:self.detailView animated:YES];
}
When I moved it to the last line (as shown above) my program would crash with an EXC_BAD_ACCESS error. I still don't understand why moving that line of code to the end of my method caused the program to crash?
However, this got me thinking - I was able to successfully change the title of the new detail view, but not the view's UILabel properties. So I moved my pushViewController method back to where it was and then moved my methods for setting the new view's UILabels underneath the pushViewController method and BOOM! Everything worked! The new detail view was being pushed when the user clicked on the row in my table and its properties (title and UILabels) were all being set correctly.
Why does this work?
I remember reading about how the iPhone handles views, something called "lazy loading" or "lazy instantiation"? I think this means that I can't change the properties of my detail view UNTIL I've "pushed" it, which is when the object is actually created in memory and its properties become available?
If this is correct, that would kind of explain the error I was getting when I moved the pushViewController method to the end of my code - I was trying to change the title property on a view that wasn't instantiated. However, that doesn't completely make sense because I was trying to change the UILabel properties of the view in my original code, which was before the view was actually pushed and the program wasn't crashing?
So my code that is currently working looks like the following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
if (self.detailView == nil) {
DetailController *detail = [[DetailController alloc] initWithNibName:#"DetailController" bundle:nil];
self.detailView = detail;
[detail release];
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[theList getItem:cell.textLabel.text]];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:self.detailView animated:YES];
// Moved the "set property" methods to happen after the detail view is pushed
[self.detailView.theID setText:#"LOOK AT ME NOW!"];
self.detailView.thePrice.text = [[dict objectForKey:#"PRICE"] stringValue];
NSString *newTitle = [[NSString alloc] initWithString: #"Viewing Attributes for: "];
newTitle = [newTitle stringByAppendingString:cell.textLabel.text];
self.detailView.title = newTitle;
[dict release];
[newTitle release];
}
I like that the code is working, but I would really like to understand what was and is actually happening. Can anyone offer additional insight here?
Thank you!
Move
[self.navigationController pushViewController:self.detailView animated:YES];
to last line.
You may try doing:
NSString *strText = [NSString stringWithFormat:#"%#",[[dict objectForKey:#"PRICE"] stringValue]];
self.detailView.thePrice.text = [NSString stringWithFormat:#"%#",strText];
Check wheather strText is containing the expected value and is not nil.