Trouble passing data between scenes when I segue - ios

I've done tutorials where I pass data through scenes with the prepareForSegue:sender: method, but right now when I try to use the passed data, it's null. I'm using a navigation controller as well.
here's the .h -
#import <UIKit/UIKit.h>
#import "TalkChatTableViewController.h"
#interface CreateChatTableViewController : UIViewController
#end
here's the .m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"idSegueMyChatsToChat"]){
TalkChatTableViewController *tctvc = [segue destinationViewController];
tctvc.chatObjectId = #"test";
NSLog(#"%#", tctvc.chatObjectId);
//succesfully logs out test
}
}
When I log in the above method, it comes out fine. But then when I go to my TalkChatTableViewController class it doesn't log out in viewDidLoad; it's null.
The header to that looks like this:
#import <UIKit/UIKit.h>
#interface TalkChatTableViewController : UITableViewController
#property (nonatomic) NSString * chatObjectId;
#end
and then finally the .m -
#import "TalkChatTableViewController.h"
#implementation TalkChatTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", self.chatObjectId);
// logs null
}
#end

TalkChatTableViewController * tctvc = (TalkChatTableViewController *)[segue destinationViewController];
This is what winded up working.

Related

Pass data from Collection View Controller to View Controller using delegates

On a button press, I am trying to send data from Collection View Controller to my View Controller. Here is what I have so far:
CollectionViewController.h
#import <UIKit/UIKit.h>
#class CollectionViewController;
#protocol CollectionViewDelegate <NSObject>
-(void) sendTest;
#end
#interface CollectionViewController : UICollectionViewController
#property (nonatomic, weak) id<CollectionViewDelegate> deligate;
#end
CollectionViewController.m
-(void) viewDidLoad {
[super viewDidLoad];
}
...
NSLog(#"check");
[self.deligate sendTest];
NSLog(#"called");
FooViewController.m
#import "CollectionViewController.h"
#interface FooViewController () <CollectionViewDelegate> {}
#end
#implementation FooViewController
- (void)viewDidLoad {
[super viewDidLoad];
CollectionViewController *controler = [[CollectionViewController alloc] init];
controler.deligate = self;
}
- (void) sendTest {
NSLog(#"Delegates are great!");
}
Unfortunaly when I call [self.deligate sendTest]; nothing happens. I know it is called, because I get the check, called logs.
The main wrong thing is that you are creating a CollectionViewController yourself, but you shouldn't. The CollectionViewController that you want is instantiated automagically by the Storyboard. How to find this view controller?
1 - Catch it during the segue in FooViewController:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
CollectionViewController *collectionViewController =(CollectionViewController *) segue.destinationViewController;
collectionViewController.deligate = self;
}
2 - Find it in within the child view controllers in FooViewController
self.childViewControllers
Does it help you?

Unwinding from Storyboard prevents Delegate from being called

I have a UIViewController several segues deep that when the use is finished, should unwind and take them back to the DashboardViewController.
I created the unwindToDashboard method in the Dashboard and hooked a button up to the Exit in my FinishViewController. So that when its clicked will fire the unwind action.
That works fine.
But I need to pass back data to the Dashboard from the FinishViewController.
So I created a delegate ProcessDataDelegate for the FinishViewController and made the Dashboard conform to it.
However, the delegate method in the Dashboard is NOT called.
Can anyone tell me what I have done wrong?
DashboardViewController.m
#import "FinishViewController.h"
#interface DashboardViewController () <ProcessDataDelegate>{
FinishViewController *fm;
}
#end
#implementation DashboardViewController
- (void)viewDidLoad {
[super viewDidLoad];
if(!fm){
fm = [[FinishViewController alloc] init];
}
fm.delegate = self;
}
- (IBAction)unwindToDashboard:(UIStoryboardSegue *)unwindSegue {
//empty
}
#pragma mark PROTOCOL METHODS
-(void) didFinishWithResults:(NSDictionary*) dictionary{
NSLog(#"Dashboard method called didFinishWithResults");
}
#end
FinishViewController.h
#class FinishViewController;
#protocol ProcessDataDelegate <NSObject>
#required
- (void) didFinishWithResults: (NSDictionary*)dictionary;
#end
#interface FinishViewController : UIViewController
#property (nonatomic, weak) id <ProcessDataDelegate> delegate;
#end
FinishViewController.m
#interface FinishViewController ()
#end
#implementation FinishViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"fired via the button to the exit--- Segue: %#", [segue identifier]);
[delegate didFinishWithResults:nil ];
}
#end
You need pass your delegate in prepareForSegue method of your DashboardViewController, there get the destinationViewController and cast to FinishViewController if the identifier is equal to your expected segue identifier
Something like this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"fired via the button to the exit--- Segue: %#", [segue identifier]);
if([[segue identifier] isEqualToString:#"YourSegueIdentifier"])
{
((FinishViewController*)[segue destinationViewController]).delegate = self
}
}

Destination view in segue gives error in property

I am trying to pass a custom object to a new view's property though it gives an error because it cannot find the "setter" for the property.
When I select a row in my table this method is called:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.actionIndexPath = indexPath;
[self performSegueWithIdentifier:SELECTED_PERSON sender:self];
}
Next:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:CREATE_EDIT_PERSON]) {
PersonDebtViewController *editPerson = [segue destinationViewController];
editPerson.editPerson = self.oweMePeople[self.actionIndexPath.row];
}
else if ([segue.identifier isEqualToString:SELECTED_PERSON]) {
EmailViewController *emailPerson = [segue destinationViewController];
emailPerson.selectedPerson = self.oweMePeople[self.actionIndexPath.row];
}
self.actionIndexPath = nil;
}
It is in the emailPerson.selectedPerson =... it goes wrong.
I have declared the property in the destinationview:
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#import "Person.h"
#interface EmailViewController : UIViewController <MFMailComposeViewControllerDelegate>
#property (nonatomic) Person *selectedPerson;
#end
What am I missing?
You probably forgot to set your view controller to a EmailViewController in Storyboard. Your error is telling you:
[UIViewController setSelectedPerson:]
Trying to send the message setSelectedPerson: to an instance of UIViewController

Passing data from a Table View Controller to a Detail View Controller

I am trying to pass an image from my TableViewController to a DetailViewController. My problem is a logic problem i guess because Xcode doesn't show any error in my code. When i tap on any row and takes me to the DetailView, the DetailView shows nothing and i want the DetailView to show me the image i am passing.
My TableViewController.h
#import <UIKit/UIKit.h>
#import "CustomCellControllerCell.h"
#import "DetailViewController.h"
#interface ListViewController : UITableViewController
#property (nonatomic) NSArray *foodImgArray;
#property (nonatomic) NSArray *foodTitleArray;
#end
My TableViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.foodTitleArray = #[#"manito",
#"jatito",
#"dolorsito",
#"pajarito",
#"calalito",
#"chinguito"];
self.foodImgArray = #[#"ajigallina.jpg",
#"anticucho.jpg",
#"causaRellena.jpg",
#"anticucho.jpg",
#"anticucho.jpg",
#"anticucho.jpg"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detailView"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
dvc.passedImage.image = [UIImage imageNamed:[self.foodImgArray objectAtIndex:indexPath.row]];
}
}
My DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *detailImage;
#property (nonatomic) UIImageView *passedImage;
#end
And my DetailViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.detailImage.image = self.passedImage.image;
}
why dont you just pass a image
like--
dvc.image=[UIImage imageNamed:[self.foodImgArray objectAtIndex:indexPath.row]];
and set that image to detailImage in DetailViewController like--
self.detailImage.image = self.image
try to put some break point to check if image in not nil in DetailViewController.

Passing data between UIViewController and UITableViewController not connected via segue

I followed the advice at this link Changing the value of a property of another UIViewController
I have a Login page that is connected to a github project that I downloaded called SWRevealViewController. It essentially provides a slide out menu for the application. I need to pass a value from my Login Page to the initial Page that is loaded with the SWRevealViewController. Can't seem to get it working. Can anyone point me in the right direction? What I have tried is the following:
LoginViewController.m
#import "LoginViewController.h"
#import "ProfileTableViewController.h"
#interface LoginViewController ()
#property (strong, nonatomic) ProfileTableViewController *secondViewController;
#end
#implementation dbViewController
-(id)init
{
if (self = [super init]) {
self.secondViewController = [[ProfileTableViewController alloc] init];
}
return self;
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
if([identifier isEqualToString:#"Login"]){
[self login:sender];
self.secondViewController.idNumber = _IDNumber;
_secondViewController.idNumber = _IDNumber;
return YES;
}
}
LoginViewController.h
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#import "ProfileTableViewController.h"
#interface LoginViewController : UIViewController
#property (strong, nonatomic)NSString *IDNumber;
#end
ProfileTableViewController.h
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#interface ProfileTableViewController : UIViewController <CLLocationManagerDelegate, UITextFieldDelegate>
#property (nonatomic) NSString *idNumber;
#end
ProfileTableViewController.m
#import "ProfileTableViewController.h"
#import "SWRevealViewController.h"
#import "ProfileEditFieldController.h"
#interface ProfileTableViewController ()
#end
#implementation ProfileTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(_idNumber);
}
#end
Just to add clarification, the two blue controllers are the Login, and the three controllers on the right, one of them is the controller I would like to pass the value for
You should do it like this instead:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ProfileTableViewController *pvc = (ProfileTableViewController*)[segue destinationViewController];
pvc.idNumber = _IDNumber
}
Hope that works! :)
UPDATE:
I think what you need is NSUserDefaults, use it, and store the ID. You gonna need it in more than one controller I believe, and its easy to store data on.
NSUserDefaults
It's not 100% clear from what you've shown but I'm assuming that these view controllers are defined in a storyboard and that the "Login" segue is also defined in the storyboard and causes a transition from LoginViewController to ProfileTableViewController.
One thing I am confused about is why the #implementation line in LoginViewController.m says "dbViewController" but I'm assuming that's a typo and that it should be "#implementation LoginViewController".
So, assuming all of that is true, there are a couple of problems in your code. First, you shouldn't be creating the ProfileTableViewController in LoginViewController's init method. iOS will automatically alloc and init the ProfileTableViewController when the segue is performed.
Second, instead of using shouldPerformSegueWithIdentifier:sender:, you want to use prepareForSegue:sender:. When that method is called, iOS will have already created the ProfileTableViewController and you can set your property.
So, what you want is something like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Login"])
{
ProfileTableViewController * viewController = segue.destinationViewController;
viewController.idNumber = _IDNumber;
}
}

Resources