NSMutableArray is not mutable anymore after passing it to another viewController - objective-c

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];
}

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];
}
}

Objective-c: passing data from UITable to ViewController with prepareForSegue

this is my very first app and, basically, this part consists in passing data from a UItableView to a second View Controll. I managed to learn how to pass data from a simple NSarray (also in a UITable), but my goal is to pass values from a NSDictionary. Everything is set up, but I can't figure out how to write the PrepareForSegue method properly. The app runs, but the label on the "DetailView" stays empty. What I got so far:
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
_citySpots = #{#"Bars" : #[#"Hurricane", #"Black Swan", #"Texas"],
#"Clubs" : #[#"Electric Wizard", #"Offspring", #"The Tunnel"],
#"Restaurants" : #[#"Nando's", #"1/2 Burguer", #"Satellite"],
};
_sectionTitles = [[_citySpots allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
PrepareForSegue Method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"spotsDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
NSString *sectionTitle = [_sectionTitles objectAtIndex:indexPath.section];
NSArray *citySpots = [_citySpots objectForKey:sectionTitle];
destViewController.receiver = [citySpots objectAtIndex:indexPath.row];
}
}
And the receiver(header):
#import <UIKit/UIKit.h>
#import "TableViewController.h"
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *receiver;
#property (nonatomic, strong) NSString *spot;
#end
Main:
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
_receiver.text =_spot;
}
Can someone help me out? Thanks
Try to use setters:
[destViewController setReceiver:[citySpots objectAtIndex:indexPath.row]];
[destViewController setSpot:[citySpots objectAtIndex:indexPath.row]];

objective-c prepareForSegue don't see variables in vc

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];

Pass values to another UIViewController

I am trying to pass values (UIImage, NSString) to another ViewController, but it wont work.
My code looks like this:
1st ViewController.m
#import 2nd ViewController.h
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
AppDetail *advc = [[AppDetail alloc] init];
if ([[segue identifier] isEqualToString:#"showDetail"]) {
advc.appTitel = name;
advc.appIcon = icon;
advc.detailAppName = detileName;
advc.appDescription = description;
}
}
2nd ViewController.h
#import <UIKit/UIKit.h>
#interface AppDetail : UIViewController
#property (strong, nonatomic) NSString *appTitel;
#property (strong, nonatomic) UIImage *appIcon;
#property (strong, nonatomic) NSString *detailAppName;
#property (strong, nonatomic) NSString *appDescription;
#end
2nd ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = self.appTitel;
self.appIconImageView.image = self.appIcon;
self.detailAppNameTextView.text = self.detailAppName;
self.appDescriptionTextView.text = self.appDescription;
}
But I always get (null) for all values!
What am I doing wrong??
Correct by this :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
// Get reference to the destination view controller
AppDetail *advcc = [segue destinationViewController];
advc.appTitel = name;
advc.appIcon = icon;
advc.detailAppName = detileName;
advc.appDescription = description;
}
}
The code below it's when you don't use storyboard :
AppDetail *advc = [[AppDetail alloc] init];
Correct these lines
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//AppDetail *advc = [[AppDetail alloc] init];
if ([[segue identifier] isEqualToString:#"showDetail"]) {
AppDetail *advc = segue.destinationViewController; //ADD THIS
advc.appTitel = name;
advc.appIcon = icon;
advc.detailAppName = detileName;
advc.appDescription = description;
}
}

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];