objective-c prepareForSegue don't see variables in vc - objective-c

This code isn't able to access a variable from ClubImageViewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
if ([[segue identifier] isEqualToString:#"mySegue"]) {
UINavigationController *navigationController = segue.destinationViewController;
ClubImageViewController *vc = (ClubImageViewController * )navigationController.topViewController;
vc. //here can't see the var from ClubImageViewController
}
}
ClubImageViewController.m:
#import "ClubImageViewController.h"
#import "KASlideShow.h"
#interface ClubImageViewController () <KASlideShowDataSource,KASlideShowDelegate>
#property (strong, nonatomic) IBOutlet KASlideShow *slideShow;
#property NSArray* imageArray;
#end
What did I miss? Is there something in the storyboard I should change?

Based on a guess that the ClubImageViewController is a regular view controller, and the OP code was picked up in a copy paste where the destination was a navigation controller, some simpler code will work...
if ([[segue identifier] isEqualToString:#"mySegue"]) {
ClubImageViewController *vc = (ClubImageViewController *)segue.destinationViewController;
// here, all will be fine with the variable vc
}
If I'm wrong, and ClubImageViewController really is a UINavigationController, then...
if ([[segue identifier] isEqualToString:#"mySegue"]) {
UINavigationController *navVC = (UINavigationController *)segue.destinationViewController;
NSArray *viewControllers = navVC.viewControllers;
ClubImageViewController *vc = (ClubImageViewController *)viewControllers[0];
// here, all will be fine with the variable vc
}

//assign an identifier to your segue from StoryBoard with string "mySegue"
//And change fetch your ViewController object by getting the root view controller. I mean look at the last line inside your if condition
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
if ([[segue identifier] isEqualToString:#"mySegue"]) {
UINavigationController *navigationController = segue.destinationViewController;
ClubImageViewController *vc = (ClubImageViewController * )[navigationController.viewControllers objectAtIndex:0];
vc. //here can't see the var from ClubImageViewController
}
Previous Line
ClubImageViewController *vc = (ClubImageViewController * )navigationController.topViewController;
New Line
ClubImageViewController *vc = (ClubImageViewController * )[navigationController.viewControllers objectAtIndex:0];

Related

Objective-C: How can i access another ViewController and change UI in it?

I'm trying to navigate to another view and change its UI.
I manage to access to the controller method "hideElements",
but all the elements are "NIL" and it doesnt change anything.
(When i access the ViewController.m regular with no navigation then the properties are not NIL)
Why is that and How can i solve it?
ViewController.m:
- (void)hideElements:(NSString *)identifier{
[_agreeButton setHidden:TRUE];
[_noThankButton setHidden:TRUE];
[self cleanButtons];
}
ViewController2.h
#import "ViewController.h"
#property (nonatomic) ViewController *myViewController;
ViewController2.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
[vc hideElements:identifire];
}
ScreenShot:
It seems that the problem is the view controller's view (and subviews including outlets) haven't been created by the time you are calling hideElements. So you can do a couple of things
1)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
vc.view;
[vc hideElements:identifire];
}
2)
ViewController2.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
vc.shouldHideElements = YES;
}
ViewController.m
- (void)viewDidLoad {
if (self.shouldHideElements) {
[self hideElements];
}
}

NSMutableArray is not mutable anymore after passing it to another viewController

I'm using NavigationController and in the MasterViewController I have a NSMutableArray called _emails, when I prepareForSegue I do this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SelectContactViewController *vc = [segue destinationViewController];
vc.delegate = self;
vc.emails = _emails;
}
in SelectContactViewController _emails is correctly filled with datas from MasterViewController _emails property, But it is no more Mutable! I can't add/remove object. Here is definition of _emails in SelectContactsViewController:
#import "MasterViewController.h"
#protocol MyViewDelegate;
#interface SelectContactViewController : UITableViewController {
id<MyViewDelegate> delegate;
}
#property (strong, nonatomic) NSMutableArray* emails;
and definition of _emails in MasterViewController:
#interface MasterViewController () {
NSMutableArray *_emails;
}
How can I pass a MutableArray to another view and still be a MutableArray??
Just change the below lines
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SelectContactViewController *vc = [segue destinationViewController];
vc.delegate = self;
vc.emails = _emails;
}
To the below lines
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SelectContactViewController *vc = [segue destinationViewController];
vc.delegate = self;
vc.emails = [_emails mutableCopy];
}

Unrecognized selector - using indexpath.row to send a string to view2

Im having trouble passing a string to a second view. I am trying to grab the indexpath.row for the selected tableviewcell and pass the associated string but keep getting "unrecognized selector.."
When using DLog the console displays the correct string. On the view im passing info. to I have an NSString setup. Thanks for any help you can provide!
Here is the prepareforsegue code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"kShowMovie"])
{
MoviePlayerNEWViewController *dvc = (MoviePlayerNEWViewController *)[segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DemoVideos *demovideo = [_tableContents objectAtIndex:indexPath.row];
dvc.videoDemoString = demovideo.vd_link;
DLog(#"Video link to pass = %#",demovideo.vd_link);
}
UIViewController * controller = segue.destinationViewController;
[controller setHidesBottomBarWhenPushed:YES];
}
The error message is saying that the controller you're trying to call setVideoDemoString: on is a UINavigationController, not a MoviePlayerNEWViewController as you think it is. You probably want this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"kShowMovie"])
{
UINavigationController *nav = segue.destinationViewController;
MoviePlayerNEWViewController *dvc = nav.topViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DemoVideos *demovideo = [_tableContents objectAtIndex:indexPath.row];
dvc.videoDemoString = demovideo.vd_link;
DLog(#"Video link to pass = %#",demovideo.vd_link);
}
UIViewController * controller = segue.destinationViewController;
[controller setHidesBottomBarWhenPushed:YES];
}

segue data passing returns nil

I need to pass a NSString to my other ViewController but it keeps returning nil.
//prepareForSegue is called from didSelectRowAtIndexPath
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"chat"]) {
NSString *userName = (NSString *) [toUsersArray objectAtIndex:[self.chatsTableView indexPathForSelectedRow].row];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ChatViewController *chatViewController = [storyboard instantiateViewControllerWithIdentifier:#"ChatViewController"];
//[chatViewController setChatWithUser:userName]; EVEN TRIED:
chatViewController.chatWithUser = username;
}
}
Here is where I declare the NSString:
#interface ChatViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, MessageDelegate> {
UITextField *messageField;
NSString *chatWithUser;
UITableView *chatTableView;
NSMutableArray *messagesArray;
}
#property (nonatomic,retain) IBOutlet UITextField *messageField;
#property (nonatomic,retain) NSString *chatWithUser;
#property (nonatomic,retain) IBOutlet UITableView *chatTableView;
- (IBAction) sendMessage;
#end
and here its still nil:
#synthesize chatWithUser;
- (void)viewDidLoad {
[super viewDidLoad];
//DO STUFF WITH chatWithUser; ADDED BREAKPOINT AND chatWithUser = nil;
//ALSO TRIED viewWillAppear;
}
What is the right way to pass data between these two View Controllers? My variables stay nil.
The problem is that you're instantiating a new ChatViewController, that's not the one that the segue is going to. You should get that controller from the segue's destinationViewController property.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"chat"]) {
NSString *userName = (NSString *) [toUsersArray objectAtIndex:[self.chatsTableView indexPathForSelectedRow].row];
ChatViewController *chatViewController = segue.destinationViewController;
chatViewController.chatWithUser = username;
}
}
// Get reference to the destination view controller
ChatViewController *ChatViewController = [segue destinationViewController];

Cannot pass value from UITableViewCell to a detail view

I am trying to change the color of a label in my detail view based on which cell is touched in a table view.
I just can't make this happen. Below is my code. I have included the header file from the detail view, and created an IBOutlet for the label.
Update: Ideally, when I clicked on a cell, the label color in detailview should be red. And here is a screencast about my problem. http://www.youtube.com/watch?v=i0nhbsNJWHY&feature=youtube_gdata_player
#pragma mark - TableView Delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"ReferenceDetail" sender:tableView];
}
#pragma mark - Segue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReferenceDetail"]) {
ReferenceDetailViewController *referenceDetailViewController = [segue destinationViewController];
UIViewController *referenceDetailView = [segue destinationViewController];
if(sender == self.searchDisplayController.searchResultsTableView) {
NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
NSString *destinationTitle = [[filteredReferenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
}
else {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *destinationTitle = [[referenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
[referenceDetailViewController.label1 setTextColor:[UIColor redColor]];
}
}
}
The problem you are having is that the outlet UILabel inside your ReferenceDetailViewController has not loaded up from the xib, yet you are trying to set it's textColor property.
As a way to make sure this is the problem, try setting a breakpoint in the line where you set the color and another breakpoint inside the ReferenceDetailViewController [viewDidLoad] method. The line where you setup the color should be getting called first.
A simple solution to your problem is to have a property on your ReferenceDetailViewController class that "holds" the UIColor instance and later set it on the viewDidLoad method:
// ...
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReferenceDetail"]) {
ReferenceDetailViewController *referenceDetailViewController = [segue destinationViewController];
UIViewController *referenceDetailView = [segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *destinationTitle = [[referenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
referenceDetailViewController.auxTextColor = [UIColor redColor];
}
// ..
And in ReferenceDetailViewController:
#interface ReferenceDetailViewController : UIViewController
#property (retain, nonatomic) UIColor *auxTextColor;
// ...
#end
#implementation ReferenceDetailViewController
- (void)viewDidLoad
{
[super viewDidLoad];
label1.textColor = self.auxTextColor;
// ...
}
#end
If you must do this for a set of labels, it'd be wise to have a NSDictionary object to hold these properties for you.
The outlets are not setup yet when you segue so you can't get to them to change them. Try sending some object or something over and in the viewdidload of the viewcontroller you segue to you read that and then use that as the way to know what color to change to and then in that same code you change the color of the label.