I sending a String from a UIButton to my next UITtableviewcontroller, the string is the UIButton Title (Monday ... Sunday) the string is used by the NSPredicate to filter my table information by day.
#property (nonatomic, weak) NSString *dayOTW;
- (IBAction)selectDay:(UIButton *)sender {
UIButton *dayW = sender;
dayOTW = dayW.titleLabel.text;
NSLog(#"button press = %#", dayOTW);
}
2012-05-01 06:23:21.731 passingdata[99957:fb03] button press = Monday
And segue to my next screen
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"SendWeekDay"])
{
// Get reference to the destination view controller
ViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
vc.dayOTW = dayOTW;
}
}
the first time I select the button no information is show in my table , if I go back and select the button again my table show with the correct information for that day .
what i am doing wrong ?
one more question related to the above .
I have 7 UIButtons one for each day on the week, how can segue from all the UIButtons with one segue ?
Thanks
The segue is being called before your IBAction method, so the variable is not set the first time you click it.
If the segue is connected to your button, then it will be the sender in prepareForSegue, so you don't really need the action method. Just get the title in prepareForSegue:
UIButton *dayButton = (UIButton*)sender
vc.dayOTW = sender.titleLabel.text;
To connect the same segue to all buttons, you have to ctrl-drag from each button, but give all segues the same identifier. This looks messy on the storyboard, so an alternative is to create a single segue directly from the source view controller, and in the action method (which you would need in this case, and would be connected to all of your buttons) call performSegueWithIdentifier:sender::
-(IBAction)dayButtonPressed:(UIButton*)sender
{
[self performSegueWithIdentifier:#"SendWeekDay" sender:sender];
}
This would then pass the button to the performSegue method as the sender, so you can use the code outlined above.
Related
I have 2 view controller
Main has a button
Detail has a label: lblDetail
I'm trying to pass data by segue : "sgPushDetail". When click on the button on Main, the label on Detail will be changed.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"sgPushDetail"]) {
DetailViewController *detail = segue.destinationViewController;
detail.lblDetail.text = #"you've already clicked";
}
}
But when i build, the label doesn't change. Please help me with this case!
The DetailViewController is not loaded when you are setting value for the label in prepareForSegue method. Do the following:
Create a property (i.e. NSString) in DetailViewController
Set the value for this property in prepareForSegue method
In viewDidLoad method of your DetailViewController, assign this property value to the label.
I have two ViewControls.
In FirstViewControl i have button and,
In SecondViewControl i have TableView,
When i click on button it should go to the TableView(SecondViewControl) and add one row ,how can i do it with programatically.I did not getting sufficient answers.Can any one help me
First thing that you should do is to create an NSMutableArray property in FirstViewController. That array needs to be filled in with all data that will be displayed on SecondViewController.
#property (nonatomic, strong) NSMutableArray *arrayOfData;
Also create a NSMutableArray property in SecondViewController. Now when you have two properties that are capable of holding data, you can go to step when Button is pressed.
- (IBAction)buttonInCellPressed:(UIButton *)sender {
[arrayOdData addObject:#"E.g. some string.";
// Call transition to second view after button is clicked
[self performSegueWithIdentifier: #"GoToSecondViewController" sender: self];
}
Code above will add new element to the array, based on what you want to add you will need some customization. Once perform segue is called you will need to copy data before view is actually displayed. You will do that in prepareForSegue method.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// This string needs to be equal to one that you put in performSegue and on that is in storyboard
if ([[segue identifier] isEqualToString:#"GoToSecondViewController"])
{
SecondViewController *vc = [segue destinationViewController];
// This is array in second view controller
vc.arrayOfData = [NSMutableArray arrayWithArray:oldArray];
}
}
Now in the new controller, use arrayOfData to fill in TableView. Also, for this solution you will need to return array to the first controller, same process as you did when you send it to second one.
If you want to improve your code, you will need to implement some object that will hold data separately from views.
Can someone point me in the right direction? I have one View Controller with multiple buttons. I want the button presses to open my custom one Table View Controller and load the data dynamically. I know I could make multiple Table View Controllers for each button press, but I was thinking there has to be a way to do this dynamically. Let me be clear that another view will determine which data to load into the Table View Controller. I'm new to iOS and Objective-C, but not programming, so take it easy on the rocket science answers. Let me know if you need to see some code.
Basically I have 4 buttons on one View Controller that when pressed will determine what data to load on the Table View. Let's keep it simple for now and just say that the data is 4 NSMutable Arrays.
EDIT:Based on babygau's post this is what I came up with:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"allCattleSegue"]) {
CattleTableViewController *controller = segue.destinationViewController;
controller.cattleArray = [[NSMutableArray alloc] initWithObjects:#"cattle1",#"cattle2",#"cattle3", nil];
}
else if ([segue.identifier isEqualToString:#"bullsSegue"]){
CattleTableViewController *controller = segue.destinationViewController;
controller.cattleArray = [[NSMutableArray alloc] initWithObjects:#"bull1",#"bull2",#"bull3", nil];
}
}
- (IBAction)allCattleTouchUpInside:(UIButton *)sender {
[self performSegueWithIdentifier:#"allCattleSegue" sender:self];
}
- (IBAction)bullsTouchUpInside:(UIButton *)sender {
[self performSegueWithIdentifier:#"bullsSegue" sender:self];
}
this gets the job done but now my navigation doesn't work properly when I press the back button. It gives me a blank screen.
UPDATE: Debugging I see that it is calling the prepareForSegue twice; once with the Controller as the sender and again with the button as the sender. Still attempting to understand how this works and how to resolve this navigation issue.
RESOLVED: Apparently I don't need the actions (TouchUpInside) wired up. Thanks for all of the help.
Hi just create one Viewcontroller and TableViewController. Set the tag fro all button and then create one #property int variable in TableViewController then do like this below..
Create common method to trigger for all button in UIControlTouchUpInside .Then in UITableViewController create int variable like this.
TableViewController.h file you create like this.
#property (nonatomic, assign) int buttonSelected;
ViewController.m create common method like this.
-(IBAction)commonMethod:(id)sender
{
TableViewController *tableVc = [[TableViewController alloc]initWithNibName:#"TableViewController" bundle:nil];
if(button.tag==0)
{
tableVC.buttonSelected = 0;
}
if(button.tag==1)
{
tableVC.buttonSelected = 1;
}
[self.navigationController pushViewController:tableVc animated:YES];
}
TableViewConroller.m file do this
-(void)viewDidLoad
{
[super viewDidLoad];
if(buttonPressed == 0)
{
tableDataSourceArray = ...
}
else if (buttonPressed == 1)
{
tableDataSourceArray = ...
}
}
I hope it helpful for you..
Assume that your table has tableViewData is an array.
In each button action, you use the following pattern code:
[self performSegueWithIdentifier:#"YOUR_IDENTIFIER" target:sender];
Implement the following segue delegate method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
YOURCUSTOMTABLEVIEWCONTROLLER *tableVC= segue.destinationViewController;
tableVC.tableViewData = YOUR_CORRESSPONDING_MUTABLE_ARRAY;
[tableVC.tableView reloadData];
}
That's it, you will have tableView display dynamically based on which button you click.
Notice: you have to create 4 segue between View Controller corresponding to 4 buttons and name the identifier for each segue. e.g #"fromButton1toTableVC", #"fromButton2toTableVC" and so on...
You could pass something like the button label or an identifier telling which mutable array to use.
if your doing the transition in code using a segue in your prepareForSegue method you can pass the value to the destination TableViewController i.e.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UITableViewController *controller = segue.destinationViewController;
controller.buttonTitle = sender;
}
Then in the button handler
[self perfomSegue:#"segue" sender:buttonTitle];
assign tag for each button. according to tag you can populate different data in table.simply take only one array.populate data to that array according to tag
if(button.tag==0)
{
//array=#[..];
}
if(button.tag==1)
{
//array=#[..];
}
.
.
.
Now use this array in cellForRowWithIndexPath delegate method
Fairly new to iOS development.
I have a ViewController embedded in a Navigation Controller.
In this ViewController I have two buttons (buttonOne and buttonTwo) which when pressed push to another view controller (ExerciseViewController).
The problem which i am facing is changing the title of the ExerciseViewController depending on which button is pressed.
So if buttonOne is pressed then title of ExerciseViewController is to be set to One.
if buttonTwo is pressed then title of ExerciseViewController is to be set to Two.
both view controllers have their own seperate classes.
..
ViewController.h - ViewController.m -
ExerciseViewController.h - ExerciseViewController.m
Thanks for any help in advance.
You can implement prepareForSegue:sender: in your ViewController. It will be called and provide the triggering button. If you set a tag on the button or check which instance it is to decide what the title should be. Then you can set the title on the seque destinationViewController.
In your XIB, you can set the tag of the buttons to '1', and '2'. Or, in your viewDidLoad you can do:
self.buttonOne.tag = 1;
self.buttonTwo.tag = 2;
Then in prepareForSegue you can do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showRecipeDetail"])
{
NSInteger tag = [(UIButton *)sender tag];
certViewController *destViewController = segue.destinationViewController;
destViewController.title = (tag == 1 ? #"One" : #"Two");
}
}
So I got a ViewController with 4 seperate buttons. When clicking on button1 TableViewController1 pops over the ViewController with a list of items. When selecting an item the TableViewController1 drops down and button1 now has the text that was selected in the table. This is all good. But when I do the exact same thing for button2 with TableViewController2 the data from button1 is reseted.
I use segues with identifiers, some of the code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showEducation"]) {
NSIndexPath *indexPath = [self.tableViewEducation indexPathForSelectedRow];
ViewController *destViewController = segue.destinationViewController;
destViewController.educationText = [tableViewArray objectAtIndex:indexPath.row];
}
}
So at the moment I got multiple segue identifiers for each button and multiple .h and .m files for the tableviews. Am I using a completely wrong technique to get this to work? I hope im clear enough, otherwise I can upload images.
Edit: I just noticed, I also have a slider on my ViewController. When clicking on a button and selecting a row in the TableView the slider gets reseted to the original position. Same problem as above kind of.
I am thinking that you're pushing to a new instance of your View Controller every time you push from either tableViewController.
Imagine that you click on one button on ViewController0, this creates an instance of tableViewController1. When you click a row, you're just using a performSegue to create a NEW instance of ViewController0, and this has its own ViewDidLoad - resetting the buttons.
(You're saying that the view "drops down", so it's modal?)
Don't use performSegue from the tableViewController back to the viewController, try using [self dismissModalViewController: withCompletion:](or something similar, can't remember), then your tableViewController should remove itself and reveal the original ViewController.
Now, you don't have a way to change the name of the button though, but that can be done by accessing the sender from the tableView, which will give you the original View Controller, and not a new instance of it.
One way of getting the sender is to use [performSegue... from ViewController0, and in it's own prepareForSegue, you could do something like
//In the first ViewController, not in the TableViewControllers
-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender{
if(sender == button1)
{
UITableViewController1 *dest = segue.destinationViewController;
[dest setSender: self];
}
}
And in TableViewController1 you'd create a variable ViewController *home;, and a method -(void)setSender:(ViewController*)sender;, so that in your didSelectRowAtIndexPath, you could now say [[(ViewController0*)home button1]setTitle:#..];, and then [dismissModalViewController..]
There are other ways to do it as well, depending on how you are pushing from your viewController to the tableViewController. And I'm sure there are easier ways to access the sender than this, but it works and is useful if you're already sending other data.