Button to Select Random Cell in tableView - xcode

How could I create a button on the Table View that when touched randomly selects one of the cells?
I know how to add Round Rect Button and all, just not the code part of selecting a random cell.
Thanks!
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipe = [recipes objectAtIndex:indexPath.row];
// Hide bottom tab bar in the detail view
// destViewController.hidesBottomBarWhenPushed = YES;
}

Hello as you have mentioned in your comment that you have only one section with 36 cells. find the rendom row using arc4random.
Then fetch your indexPath from section and row.
then call didSelectRowAtIndexPath
Whole code of your button click method will look like....
int section = 0;
int row = arc4random() %35;
NSIndexPath * path = [NSIndexPath indexPathForRow:row inSection:section];
if ([self.yourTableView.delegate respondsToSelector:#selector(tableView:willSelectRowAtIndexPath:)]) {
[self.yourTableView.delegate tableView:self.yourTableView willSelectRowAtIndexPath:path];
}
[self.yourTableView selectRowAtIndexPath:path animated:YES scrollPosition: UITableViewScrollPositionNone];
if ([self.yourTableView.delegate respondsToSelector:#selector(tableView:didSelectRowAtIndexPath:)]) {
[self.yourTableView.delegate tableView:self.yourTableView didSelectRowAtIndexPath:path];
}
Then implement didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = indexPath.row;
[self performSegueWithIdentifier:#"showRecipeDetail" sender:btn];
}
Make sure that you have written following code in viewDidLoad
self.yourTableView.delegate = self;
self.yourTableView.dataSource = self;
And change prepareForSegue method as below
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showRecipeDetail"]) {
RecipeDetailViewController *destViewController = [segue destinationViewController];
NSInteger tagIndex = [(UIButton *)sender tag];
destViewController.recipe = [recipes objectAtIndex:tagIndex];
}
}
This will surely help you.....

Related

How do I include section information in indexPathForSelectedRow

I have a table with sections, populated by an array which is comprised of four arrays. How do I modify the indexPathForSelectedRow statements in the prepare for segue method to include section information?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
//grassType.selectedPlant = [grassArray objectAtIndex:selectedRowIndex.row];
grassType.selectedPlant = [plantArray objectAtIndex:selectedRowIndex.row];
}
}
This works perfectly for one section, but what do I do for four sections?
Declare 2 NSIntegers in the .h file
NSInteger selectedSection;
NSInteger selectedRow;
and now in your viewDidLoad(), initialize these to "-1"
selectedSection = -1;
selectedRow = -1;
Now in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedSection = indexPath.section;
selectedRow = indexPath.row;
//Now performSegue here
}
After that
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
if(selectedSection == 0){
grassType.selectedPlant = [firstArray objectAtIndex:selectedRow];}
else if(selectedSection == 1){
grassType.selectedPlant = [secondArray objectAtIndex:selectedRow];}
else if(selectedSection == 2){
grassType.selectedPlant = [thirdArray objectAtIndex:selectedRow];}
else if(selectedSection == 3{
grassType.selectedPlant = [fourthArray objectAtIndex:selectedRow];}
}
}
Hope This Helps
Thanks for all the help and guidance. The answer was distressingly simple, type in the complete and correct path for the appropriate item in the table. See below:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
grassType.selectedPlant = [[plantArray objectAtIndex:selectedRowIndex.section]objectAtIndex:selectedRowIndex.row];
}
}

Passing Detail from tableview Controller

I am trying to push my detail view I am using a PFQueryTableView and I persume it was just same as normal so I was using this.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check that a new transition has been requested to the DetailViewController and prepares for it
if ([segue.identifier isEqualToString:#"destinationViewController"]){
// Capture the object (e.g. exam) the user has selected from the list
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
dettailViewController *controller = (dettailViewController *) segue.destinationViewController;
controller.clinics = object;
}
}
But it bombs out at the *controller line I have a navigation controller on my storyboard.
When I say it bombs out it complains here
PFObject *object = [self.objects objectAtIndex:indexPath.row];
vc.clinics = object;
and saids thread error
If you are using a nav controller you need to specify the navigation controller in your segue like so:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
UINavigationController *nav = [segue destinationViewController];
EventDetail *detailViewController = (EventDetail *) nav.topViewController;
detailViewController.event = object;
}
}

IOS 7 Xcode Search Bar Controller Implementation

Sunny Thank you for your reply. I made the following changes and now by clicking on a tablecell or search result, I am pushed to DetailViewController but, for any cell I click on I get the same DetailView. I need the detail view to show different information depending on the cell I click on.
I added this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier: #"ShowDetails" sender: self];
}
}
New segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
detailviewcontroller.DetailModal = #[_Title[row],_Attribute[row]];
}
}
update:
The reason I am having difficulty in implementing your code is because my information to be passed to the detailview is in DetailViewController.h but as an array not a string:
#property (nonatomic,strong) NSArray *Title;
#property (nonatomic,strong) NSArray *Attribute;
in the viewdidload I get these from my plist:
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
_Title = [dict objectForKey:#"caseName"];
_Attribute= [dict objectForKey:#"attribute"];
the table view is populated with said data with the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableViewCell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.TitleLabel.text = self.Title[indexPath.row];
cell.AttributeLabel.text = self.Attribute[indexPath.row];
}
return cell;
}
Then in the DetailViewController.h:
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (nonatomic,strong) IBOutlet UILabel *AttributeLabel;
#property (nonatomic,strong) NSArray *DetailModal;
DetailViewController.m:
_TitleLabel.text = _DetailModal[0];
_AttributeLabel.text = _DetailModal[1];
My segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
detailviewcontroller.DetailModal = #[_Title[row],_Attribute[row]];
}
}
I thought it would help to put more of my code so you're able to get clearer picture. In my non expert opinion, I think the reason your code doesn't work for me is because my data is being stored in an array (DetailModal) and not in a string.
Thank you for taking the time to help me with this
You should implement TableView delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
else {
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
}
Update:
You have to set the value to be displayed in the detailed view. You might declare a property in the header file for your detailView which you might set in prepareForSegue (or in the didSelectRowAtIndexPath above). For example, in DetailViewController you might do this:
#interface DetailViewController: UIViewController
#property (weak, nonatomic) NSString *myDetailValue;
#end
Then in tableView: didSelectRowAtIndexPath: above, set the correct value before you do the segue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (tableView == self.searchDisplayController.searchResultsTableView) {
// TODO select value from filteredList to set the detailViewController, e.g.:
self.detailedViewController.myDetailValue = valueFromFilteredListForIndexPath;
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
else {
// TODO select value from regular list to set the detailViewController, e.g.:
self.detailedViewController.myDetailValue = valueFromRegularListForIndexPath;
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
}
Similarly, you can do it the prepare for segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath;
if (self.inSearch) {
myIndexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
detailedViewController.myDetailValue = valueFromFilteredListForIndexPath;
}
else {
myIndexPath = [self.tableView indexPathForSelectedRow];
detailedViewController.myDetailValue = valueFromRegularListForIndexPath;
}
}
}

UITableView Segue

Im trying to make a small project. Could someone help me understand why the segue does not work?
#import "CarTableViewController.h"
#import "CarTableViewCell.h"
#import "CarDetailViewController.h"
#interface CarTableViewController ()
#end
#implementation CarTableViewController
#synthesize carMakes = _carMakes;
#synthesize carModels = _carModels;
#synthesize carImages = _carImages;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc]
initWithObjects:#"Chevy",
#"BMW",
#"Toyota",
#"Volvo",
#"Smart", nil];
self.carModels = [[NSArray alloc]
initWithObjects:#"Volt",
#"Mini",
#"Venza",
#"S60",
#"Fortwo", nil];
self.carImages = [[NSArray alloc]
initWithObjects:#"chevy_volt.jpg",
#"mini_clubman.jpg",
#"toyota_venza.jpg",
#"volvo_s60.jpg",
#"smart_fortwo.jpg", nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return _carModels.count;
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"carTableCell";
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CarTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.makeLabel.text = [self.carMakes
objectAtIndex: [indexPath row]];
cell.modelLabel.text = [self.carModels
objectAtIndex:[indexPath row]];
UIImage *carPhoto = [UIImage imageNamed:
[self.carImages objectAtIndex: [indexPath row]]];
cell.carImage.image = carPhoto;
return cell;
}
The code work´s fine, and loads a tableView, but I need to go to CarDetailViewControler and I´m using the following code, but it does not work.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowCarDetails"])
{
CarDetailViewController *detailViewController =
[segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView
indexPathForSelectedRow];
detailViewController.carDetailModel = [[NSArray alloc]
initWithObjects: [self.carMakes
objectAtIndex:[myIndexPath row]],
[self.carModels objectAtIndex:[myIndexPath row]],
[self.carImages objectAtIndex:[myIndexPath row]],
nil];
}
}
In the storyboard did you use a cell prototype? If so, did you control-drag from the prototype to the destination viewcontroller and create the named segue?
The method you are using requires the segue to be defined completely in the storyboard, meaning the trigger for the segue is tied to the cell prototype.
You can manually trigger a segue using:
[self performSegueWithIdentifier:#"ShowCarDetails" sender:self];
in your:
tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath as an alternative.

Using segues to display a UIView from UITableViewController

I am trying to connect a UITableViewController to a UIView using storyboards. I have a TabBarController that connects to a Navigation Controller that displays a UITableViewController, displaying a small array. I want to click on a row and that trigger a simple UIView with a label, still displayed in the UINavigationController so I can navigate back to the UITableViewController
I can get the UITableViewController to display OK, with the array, but I can't get the row to trigger when I select it.
This is my UITableViewController (AtoZController.m) file:
#import "AtoZController.h"
#import "StoreDetailsView.h"
#interface AtoZController ()
#end
#implementation AtoZController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(#"A to Z", #"An A to Z List of Stores");
AtoZArray = [[NSMutableArray alloc] init];
[AtoZArray addObject:#"Apple"];
[AtoZArray addObject:#"Boots"];
[AtoZArray addObject:#"Topman"];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [AtoZArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSInteger row = [indexPath row];
cell.textLabel.text = [AtoZArray objectAtIndex:row];
return cell;
}
I have a segue connected, named storeDetailsSegue, from the UITableViewController to a UIView. I am attempting to use the prepareForSeque method to trigger the next view but have had no luck with the following code.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
StoreDetailsView *detail = [self detailForIndexPath:path];
[segue.destinationViewController setDetail:detail];
}
As it keeps saying there is an error as there is 'No visible #interface for "AtoZController declares the selector 'detailForIndexPath'". I may be doing something completely wrong as I have never used storyboards before. What I want is for a simple UIView to display a label that dynamically changes to display the row number that has been selected.
I don't know if the UITableViewController should infact be a UITableView but as I have never used segues or storyboards I have no idea what could be causing the problem.
Any advice at all would be greatly appreciated.
UPDATE:
So I managed to get the UIViewController to display but still can't get the label to update before I display the view.

Resources