Can someone tell me why my values are not being sent from a UIViewController to a UITableViewController?
In my UIViewController I have a number of buttons created programatically and each button has its own tag number set as below:
bySeaButton = [UIButton buttonWithType:UIButtonTypeCustom];
bySeaButton.tag = 4;
bySeaButton.frame = CGRectMake(20, 294, 280.f, 40.f);
UIImage *seaButton = [UIImage imageNamed:#"gettingHereBySeaButton.png"];
[bySeaButton setBackgroundImage:seaButton forState:UIControlStateNormal];
[self.view addSubview:bySeaButton];
[bySeaButton addTarget:self action:#selector(bySeaButtonClicked) forControlEvents:UIControlEventTouchUpInside];
Then in my prepareForSegue I set the tagVale in my UITableViewController to the buttons tag number as follows:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
MyTableViewController *vc = [[MyTableViewController alloc] init];
vc.tagNumber = bySeaButton.tag;
}
A NSLog here shows that the vc.tagNumber is set to the buttons tag number. However, when I access the value for the tagNumber in the UITableViewController, it is always set to 0. Below is how I use it (tagNumber is declared in .m of UITableViewController as #property (nonatomic, assign) int tagNumber;)
NSString *strFromInt = [NSString stringWithFormat:#"%d", self.tagNumber];
Output for this is always 0 - regardless of the buttons tag value
try this code in preparesegue
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
MyTableViewController *vc = segue.destinationViewController;
vc.tagNumber = bySeaButton.tag;
}
first declare segue id in storyboard ,after add this method in target
[self performSegueWithIdentifier:#"push segue id" sender:self];
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"push segue id"])
{
MyTableViewController *vc = [segue destinationViewControlle];
vc.tagNumber = bySeaButton.tag;
}
}
Related
I'm trying to send the captured image to another UIViewController.
So when I press captured button, it's taking a photo and I can save the image in my camera roll. But when I want to see image in another view I can't see it.
This is my code :
- (IBAction)captureButton:(id)sender
{
[self.cameraViewController captureImageWithCompletionHander:^(id data) {
self.image = ([data isKindOfClass:[NSData class]]) ? [UIImage imageWithData:data] : data;
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
[self performSegueWithIdentifier:#"savingSegue" sender:self];
}];
}
And this is the prepare for segue method.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"savingSegue"]) {
PhotoSaveViewController *pvc = [[PhotoSaveViewController alloc] init];
[pvc.imageView setImage:self.image];
}
}
If your second view is a PhotoSaveViewController then replace your prepareForSeque method with this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"savingSegue"]) {
PhotoSaveViewController *pvc = (PhotoSaveViewController *)segue.destinationViewController;
if (pvc)
[pvc.imageView setImage:self.image];
}
}
Indeed, it's not your job to instantiate the destination UIViewController, your UINavigationController have already done that.
I guess that imageView on PhotoSaveViewController it is outlet and it is not set at this moment. You should declare there some other property like
#property (nonatomic, retain) UIImage *inputImage;
and assign to that in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"savingSegue"]) {
PhotoSaveViewController *pvc = segue.destinationViewController;
pvc.inputImage = self.image;
}
}
Then do the following in the PhotoSaveViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView.image = self.inputImage;
}
Another approach you can create it from code totally. Assign Storyboard ID to the PhotoSaveViewController and then do the following:
- (IBAction)captureButton:(id)sender {
[self.cameraViewController captureImageWithCompletionHander:^(id data) {
self.image = ([data isKindOfClass:[NSData class]]) ? [UIImage imageWithData:data] : data;
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
PhotoSaveViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"PhotoSaveViewControllerID"];
dvc.inputImage = self.image;
[self.navigationController pushViewController:dvc animated:YES];
}];
}
i make my custom tab bar using segue it's run successfully , now i try to pass data between two view controller which is on tab bar view controller
my code for tab bar controller
- (void) perform {
ViewController *ctbcv = (ViewController *)self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
for(UIView *view in ctbcv.placeholder.subviews)
{
[view removeFromSuperview];
}
ctbcv.currentViewController = dst;
[ctbcv.placeholder addSubview:dst.view];
}
and segue condition
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"HomeSegue"]
|| [segue.identifier isEqualToString:#"DeveloperSegue"]
|| [segue.identifier isEqualToString:#"DesignerSegue"]|| [segue.identifier isEqualToString:#"btn4"]){
NSLog(#"%lu",(unsigned long)[self.buttons.subviews count]);
for (int i=0; i<[self.buttons.subviews count];i++) {
UIButton *button = (UIButton *)[self.buttons.subviews objectAtIndex:i];
[button setSelected:NO];
}
UIButton *button = (UIButton *)sender;
NSLog(#"%ld", (long)button.tag);
btnclicked = button.tag;
[button setSelected:YES];
}
}
this code run successfully, now i create button on 1st view controller and give segue to the new view controller , it's crash when click on button.
- (void)viewDidLoad {
[super viewDidLoad];
[btnnext addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(void) buttonClicked:(UIButton*)sender
{
NSLog(#"you clicked on button %ld", (long)sender.tag);
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
navVC *vc = [segue destinationViewController];
}
}
After this code it crash and Xcode show "THREAD 1: EXC_BAD_ACCESS(code=2 , address = 0xc)" any solution ?
i use this reference for making custom tab bar
i make button which open new view controller in this tab bar.
Thank You
just check out that u have put your code in the main controller that you wants to use and not in tabs of tab bar controller.
i am new to ios programming. i have a static tableViewController in which i have 3 cells. i have another view controller where there is a label and description. what i am trying to do is detect the cell which user clicks and then change the label which is in my second view controller according to that but the problem is whenever i click the cell the program crashes and added the breakpoint
here is my code
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *name;
NSString *description;
if([[segue identifier] isEqualToString:#"PushAppDetailsFromCell1"] )
{
name = #"Label 1 ";
description = #"Long description of Label 1...";
}
else if([[segue identifier] isEqualToString:#"PushAppDetailsFromCell2"] )
{
name = #"Label 2";
description = #"Long description of Label 2...";
}
else if([[segue identifier] isEqualToString:#"PushAppDetailsFromCell3"] )
{
name = #"Label 3";
description = #"Long description of Label 3...";
}
else {
return;
}
AppDetailsViewController *apDetailsViewController =
segue.destinationViewController; //here i am getting the breakpoint
apDetailsViewController.appDetails =
[[AppDetails alloc] initWithName:name description:description];
}
AppDetails.m
-(id)initWithName:(NSString *)name description:(NSString *)descr{
self = [super init];
if(self){
self.name = name;
self.description = descr;
}
return self;
}
AppDetailsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.nameLabel.text = self.appDetails.name;
self.descriptionLabel.text = self.appDetails.description;
}
Steps to figure out the problem
1) Put a break point in prepareForSegue
2) Try to see it displays correct segue id as it should be(there might be making spelling mistake).
3) see where it's crashing in
- In prepareForSegue?
- Is this calling initname()?
- has it started it viewDidLoad().
If you do this mostly you will figure out what the problem is. If you can not then let me know.
Bind segue from UIViewController to UIViewController rather then cell to UIViewController. Implement following code for navigation.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"%ld",aIntSelected);
NSLog(#"%#",segue.destinationViewController);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
aIntSelected=indexPath.row;
NSLog(#"didSelectRowAtIndexPath called");
[self performSegueWithIdentifier:#"pushSecond" sender:self];
}
NSArray *names = #[#"Label 1", #"Label2", #"Label 3"];
NSArray *descs = #[#"Description 1", #"Description", #"Description 3"];
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"PushAppDetailsSegue"]) {
NSIndexPath *indexPath = [self.yourTableView indexPathForSelectedRow];
AppDetailsViewController *controller = segue.destinationViewController;
controller.appDetails = [[AppDetails alloc] initWithName:names[indexPath.row] description:descs[indexPath.row]];
}
}
Drag a segue from your ViewController to SecondViewController and name it "PushAppDetailsSegue".
I am solving this issue about 2 weeks and only be able to pass string, not image.
I store the image from camera or from library in this method.
-(IBAction)saveAction:(id)sender
{
Tricks *trick = [[Tricks alloc]init];
trick.trickName = self.trickLabel.text;
trick.trickPhoto = [[UIImageView alloc] initWithFrame:CGRectMake(0, 356, 320, 305)];
trick.trickPhoto.image = self.ImagePhoto.image;
[[Tricks trickList]addObject:trick];
}
In tableViewClass I store the values into properties of detailView
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"detailTrick"]){
NSIndexPath *indexPath = nil;
indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
Tricks *trick = [[Tricks trickList] objectAtIndex:indexPath.row];
detailViewController.trickPhoto = [[UIImageView alloc]initWithFrame:CGRectMake(0, 358, 200, 200)];
detailViewController.fileText = trick.trickName;
detailViewController.trickPhoto = trick.trickPhoto;
//object = [Tricks trickList][indexPath.row]
}
}
Text showed up every time without problems, but there is no image in detailViewController.Thanks for help.
viewDidLoad of detailViewController
[super viewDidLoad];
[self.detailButton setTitle:[NSString stringWithFormat:#"%#",_fileText] forState:UIControlStateNormal];
[self.trickPhoto setImage:_trickPhoto.image];
First off, trickPhoto within the Trick class should be a UIImage, not a UIImageView. Models shouldn't know anything about views such as frames, etc so right now you're violating the MVC design pattern.
Then it'd be:
- (IBAction)saveAction:(id)sender
{
Tricks *trick = [[Tricks alloc] init];
trick.trickName = self.trickLabel.text;
trick.trickPhoto = self.ImagePhoto.image;
[[Tricks trickList] addObject:trick];
}
The better way of doing this would be to create a Trick property within DetailViewController and just pass the whole trick into the view controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"detailTrick"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
Tricks *trick = [[Tricks trickList] objectAtIndex:indexPath.row];
NSLog(#"Make sure trick isn't nil: %#", trick);
detailViewController.trick = trick;
}
}
Then you'd just populate it with:
[super viewDidLoad];
[self.detailButton setTitle:[NSString stringWithFormat:#"%#", self.trick.trickName] forState:UIControlStateNormal];
[self.trickPhoto setImage:self.trick.trickPhoto];
Is this piece of code suppose to set the title on the ViewController I am connecting to?
The 2 UIViewControllers are connected via a push segue - the first one is embedded in a NavigationController.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"settingsSegue"])
{
self.navigationItem.title = [[NSString alloc] initWithFormat:#"Custom Title"];
}
}
It does not work for me, but the syntax is right.
Advance Thanks:-)
The above answer works for me with one exception...
Change
self.title = myTitle;
to
self.navigationItem.title = myTitle;
Set the title in the viewDidLoad of the destination viewcontroller using a property in the destination VC:
if ([[segue identifier] isEqualToString:#"settingsSegue"]) {
MyDestinationViewController *mdvc = segue.destinationViewController;
mdvc.myTitle = [[NSString alloc] initWithFormat:#"Custom Title"];
}
Then in the viewDidLoad event in MyDestinationViewController.h:
#property (nonatomic,strong) NSString *myTitle;
In MyDestinationViewController.m:
#synthesize myTitle;
And finally in viewDidLoad:
self.title = myTitle;
You can set the title directly in the segue as well, there is no need to go through a property:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"settingsSegue"]) {
segue.destinationViewController.navigationItem.title = #"Custom Title";
}
}
Or, what I needed, to set the title of the pushed view controller to the title of the table cell that was clicked:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"settingsSegue"]) {
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:myIndexPath];
segue.destinationViewController.navigationItem.title = cell.textLabel.text;
}
}