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.
Related
I am having issues displaying data in a tableview from a push segue. How do you make data appear in the tableview from the push segue? Do I need to implement a delegate/protocol? What method would I add my logic to display the rows in the TableViewController from the push segue. I able to navigate to the tableview and back to the button sort view controllers.
Can someone show me the process similar how I wrote My Logic? I am stuck on step 4. If you have a easier way to execute please let me know.
Controllers I am trying to coordinate.
"EventFeedController.m " TableViewController executed from Tab Bar Controller. This shows the events.
" ButtonSort.m " to push segue to EventFeedController.m
AppDelegate.m has array.
My Logic...
In the storyboard.
Control drag from UIButton in ButtonSort directly to EventsFeedViewController (not to the navigationcontroller but directly to the view EventViewController itself. ). (Not sure if I should control drag to view controller or the navigation controller of EventsfeedViewController)
Select push segue from popup of the control drag
Give Button a identifier of Button01 (This would find items array where eventFeed.eventType = #"Festival";) So for clarity Button01 = Find events with eventFeed.eventType = #"Festival";
Step I am stuck on. Not sure how to access or display the array created in AppDelegate.m didFinishLaunchingWithOptions paragraph. I thought cellForRowAtIndexPath in EventsFeedViewController would be responsible for being called and displaying the rows again.
Sample of array code AppDelegate.m
Events array created AppDelegate.m. I need to pull the event when clicking the push button segue.
_events = [NSMutableArray arrayWithCapacity:20];
//***************************************
// Event feed related area
//***************************************
SDEventsFeed *eventFeed = [[SDEventsFeed alloc] init];
eventFeed.eventTitle = #"Event Fest Test 1";
eventFeed.eventDescription = #"This is not to be missed";
eventFeed.eventStartTime = #"2:00 PM";
eventFeed.eventImage = [UIImage imageNamed:#"fest.jpg"];
eventFeed.eventType = #"Festival";
[_events addObject:eventFeed];
In the table view controller that you want to push to display the data, you will need to add a property to hold that data. Something like the following:
#property (nonatomic, strong) MyDataClass *myData;
Then in the view controller that you're pushing from (the one with the button that pushes the table view controller), you'll want to add a method - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. You can implement it in a way like the following:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YourSegueIdentifierFromStoryboard"]) {
YourTableViewControllerClass *viewController = segue.destinationViewController;
viewController.myData = self.myData;
}
}
To pull the data from the AppDelegate you would need to do the following.
Make sure you import the AppDelegate.h into your class doing the segue.
You can create a NSMutableArray property in AppDelegate.h to hold the array data "eventArray".
This is just one possible solution.
ButtonSort.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Button01"]) {
YourTableViewControllerClass *viewController = segue.destinationViewController;
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
viewController.events = appDelegate.eventsArray;
}
}
In my app, I have 4 view controllers, (login,welcome,game view and results view). In the game view, I have two additional views (like this)[screen shot link to the views]. I am using a web api to get data, and my data is consist of items(each item has 1 image and 4 string). Item number is not constant so based on the amount of items(which I store it inside an array), I transition my views from one to another until I ran out of items.(The way I present is really similar to view transitions sample from apple. After displaying the last item, I use perform segue to go to next view.
The problem that I am trying to solve
I am trying to create an additional view/ or view controller that uses some part of the information from my items array.
my question
Why I am getting null for container views array ?(_results array is the array that has the items)
this is what I tried:
based on this question:
GameView
ContainerViewController *container = [[ContainerViewController alloc]init];
container.array = _results;
[self performSegueWithIdentifier:#"changetoResults" sender:self];
ContainerViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"items in the array - containerviewcontroller.m %#",array);
}
this is the console:
2013-11-26 19:11:29.157 GuessTheImage[3664:70b] there are 8 , of items in the current index -gameviewcontroller.m
2013-11-26 19:12:44.439 GuessTheImage[3664:70b] items in the array - containerviewcontroller.m (null)
Thank you.
Because the ViewController that you create isn't the ViewController that you go to via the segue.
If you'd like to use a segue, you can get the destination ViewController (it already exists) in a prepareForSegue method and tune it however you want (in your case - add an array).
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"changetoResults"])
{
ContainerViewController *vc = (ContainerViewController *)[segue destinationViewController];
vc.array = _results;
}
}
There are two things that you are not doing correctly:
You are setting the array on a temporary view controller different from the instance activated by your segue, and
You are logging the array too early: viewDidLoad: is called before the segue code manages to put the array into the new view controller.
To fix the first problem, remove the two lines above the "perform segue" call, and add this method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"changetoResults"]) {
ContainerViewController *container = segue.destinationViewController;
container.array = _results;
}
}
To fix the second problem, move the logging code into the viewDidAppear:. NSLog should start showing the correct number of items.
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
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.
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.