Scroll to specific cell in UITableView with cell property - ios

I have an example of UITableViewCell as below:
//
// ItemTableViewCell.h
//
#import <UIKit/UIKit.h>
#interface ItemTableViewCell : UITableViewCell
#property (weak, nonatomic) NSString *itemId;
#end
In my UIViewController with UITableView I have the below assigning :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *row = [self.itemsFRC objectAtIndexPath:indexPath];
ItemTableViewCell *cell = (ItemTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
cell.itemId = [row valueForKey:#"item_id"];
}
Now, how can I scroll to specific cell in UITableView with it's cell property itemId?
Note: I highly prefer to not to use indexPathForRow method.

You should do the following:
Find NSManagedObject by item_id
Get indexPath of found object from NSFetchedResultsController
Scroll tableView to that indexPath
See code example below:
- (void) scrollToRowWithItemID: (NSString *) itemID {
NSArray *fetchedObjects = self.itemsFRC.fetchedObjects;
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"item_id == %#", itemID];
NSArray *filteredArray = [fetchedObjects filteredArrayUsingPredicate: predicate];
NSIndexPath *indexPath = [self.itemsFRC indexPathForObject: filteredArray.firstObject];
[self.tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionNone animated: true];
}

Related

iOS: How to display parameters in response in tableview?

I am trying to set up a UITableView inside of a UIViewController. I am using storyboard. but when running it on the simulator, the tableview does not display any content. Here is what i tried in Xcode:
1) Drag a table view on UIView.
2) Connect it's outlets (dataSource and delegate).
3) I get response from server like:
[{"email_id":"adas#faga.gs","id":66,"mobile_no":"1236547895","name":"asad","relation":"dsfs"},{"email_id":"raj#ghj.com","id":67,"mobile_no":"5632145412","name":"raj","relation":"xyz"}]
4)Now what i want to do:
In 1st cell i want to display,
name:asad mobile:1236547895 email:adas#faga.gs relation:dsfs
and in 2nd cell,
name:raj mobile:5632145412 email:raj#ghj.com relation:xyz
But i have no idea about how to do this.Please anyone can solve my issue. help will be appreciable.
I do like following way but it's not working.
a) Add a new file to the project, with the Objective-C class template. Name it EmergencyContactCell and make it a subclass of UITableViewCell.
b) then in EmergencyContactCell.h
#interface EmergencyContactCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *name;
#property (nonatomic, weak) IBOutlet UILabel *email;
#property (nonatomic, weak) IBOutlet UILabel *mobile;
#property (nonatomic, weak) IBOutlet UILabel *relation;
c) then MainStoryboard.storyboard, select the prototypecell and in the Identity Inspector change its class to EmergencyContactCell
d) Then connect all outlets
e) I am using AFNetworking to take response from server, when i got response, after that i do like following way:
NSArray *ResponseArray = [NSJSONSerialization JSONObjectWithData: responseObject options: kNilOptions error: nil];
if (ResponseArray.count >0)
{
menuItems = [ResponseArray mutableCopy];
[yourTableviewname reloadData];
}
f) and for display it on cell,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EmergencyContactCell";
//static NSString *simpleTableIdentifier = #"cell";
EmergencyContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
// NSDictionary *content = [menuItems objectAtIndex:indexPath.row];
// cell.textLabel.text = [NSString stringWithFormat:#"Name:%#, Mobile:%#, Email:%#, Relation:%#",content[#"name"],content[#"mobile_no"],content[#"email_id"],content[#"relation"]];
//
return cell;
}
I'm not getting what to do at last??
Step-1
No need of this
NSArray *ResponseArray = [NSJSONSerialization JSONObjectWithData: responseObject options: kNilOptions error: nil];
NSMutableArray *finalArray = [NSMutableArray array];
for (NSDictionary *temp in ResponseArray) {
[finalArray addObject:temp[#"name"]];
}
NSLog(#"%#",finalArray);
if(finalArray != nil && finalArray.count > 0){
menuItems=[NSArray arrayWithArray:finalArray];
NSLog(#"menu items: %#",menuItems);
}
else{
NSLog(#"zero values from server");
}
Simply Do like
NSArray *ResponseArray = [NSJSONSerialization JSONObjectWithData: responseObject options: kNilOptions error: nil];
if (ResponseArray.count >0)
{
menuItems = [ResponseArray mutableCopy];
[yourTableviewname reloadData];
}
Step-2
for your answer continution
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSDictionary *content = [menuItems objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"Name:%#, Mobile:%#, Email:%#, Relation:%#",content[#"name"],content[#"mobile_no"],content[#"email_id"],content[#"relation"]];
return cell;
}
Updated Answer
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EmergencyContactCell";
EmergencyContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *content = [menuItems objectAtIndex:indexPath.row];
cell.name.text = [NSString StringWithFormat:#"Name:%#",content[#"name"]];
cell.email.text = [NSString StringWithFormat:#"email:%#",content[#"email"]];
cell.mobile.text = [NSString StringWithFormat:#"mobile:%#",content[#"mobile"]];
cell.relation.text = [NSString StringWithFormat:#"relation:%#",content[#"relation"]];
return cell;
}
You need to do 2 things
After getting response set that into one NSArray. Declare NSArray
global one. And your code should be like
NSArray *arrayPersonalInfo = responseObject; // responseObject is response
got from server. Then call [tableView reloadData];
Now update your table view methods to
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return arrayPersonalInfo.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSDictionary *dictionaryMenu = [arrayPersonalInfo objectAtIndex:indexPath.row]; // It will save dictionary object of index
cell.textLabel.text = [NSString stringWithFormat:#"Name:%# Mobile:%# Email:%# Relation:%#",[dictionaryMenu valueForKey:#"name"],[dictionaryMenu valueForKey:#"mobile_no"],[dictionaryMenu valueForKey:#"email_id"],[dictionaryMenu valueForKey:#"relation"]];
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
return cell;
}
If needed add other table view methods like
heightForRowAtIndexPath and numberOfSections
If you prefer using storyboard, you can actually add a label into a prototype cell, make sure you set the prototype's cellIdentifier correctly to use it in codes. Then set a unique tag to your label. From your codes you can call viewWithTag from your cell's contentView to get the label and edit it's text property.

UISearchBar + array of objects + NSpredicate

Would you please tell me why my SearchBar doesn´t work in my UITableViewController?
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"SELF.TitleInside contains[c] %#",
searchText];
filteredArray = [HelpList filteredArrayUsingPredicate:predicate];
}
Why
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier =#"Cell";
TableViewCell_Rts *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell){
cell = [[TableViewCell_Rts alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
CellObject *NewIndex = nil;
if (tableView == self.tableView) {
NewIndex = [HelpList objectAtIndex:indexPath.row];
cell.TitleLabel2.text = NewIndex.TitleInside;
cell.DescriptionLabel2.text = NewIndex.DescriptionInside;
} else {
NewIndex= [filteredArray objectAtIndex:indexPath.row];
cell.TitleLabel2.text = NewIndex.TitleInside;
cell.DescriptionLabel2.text = NewIndex.DescriptionInside;
}
CellObject is a NSObject:
#interface CellObject : NSObject
#property (nonatomic, strong) NSString *ImageInside;
#property (nonatomic, strong) NSString *TitleInside;
#end
When i run the application, my tableview looks populated. Then, when i write inside the search bar, the table doesn´t show the results of the search.
Thanks ¡

search bar for tableview

I need to add a search bar for a table view.Table contain "Names" which is actually stored in inside an object called "patient".I have an array of "patient" objects.
So to setup a search bar to search for names.But how to do it using NSPredicate?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* CellId= #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellId] ;
}
cell.accessoryType = UITableViewCellAccessoryNone;
ObjPatient = [allPatientDetails objectAtIndex:indexPath.row];
cell.textLabel.text =[NSString stringWithFormat:#"%# %#",ObjPatient.firstName,ObjPatient.lastName];
return cell;
}
Above is the code to show the names on table.
Any suggestions are welcome , Thanks
To Implement search functionality first take look into below links -
https://developer.apple.com/library/ios/documentation/uikit/reference/UISearchBar_Class/Reference.html
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html
Then make changes in your code as follows -
In your .h file declare array -
NSArray *filteredArray;
In - (void)viewDidLoad method -
filteredArray = allPatientDetails;
Then implement UISearchBar delegate method-
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"SELF.firstName contains[c] %#",
searchText];
NSArray *filteredArray = [allPatientDetails filteredArrayUsingPredicate:predicate];
[tableView reloadData];
}
and make changes in your existing method -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString* identifier= #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] ;
}
cell.accessoryType = UITableViewCellAccessoryNone;
ObjPatient = [filteredArray objectAtIndex:indexPath.row];
cell.textLabel.text =[NSString stringWithFormat:#"%# %#",ObjPatient.firstName,ObjPatient.lastName];
return cell;
}
well for nspredicate with custom object can be done like this.
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF.firstName contains[c] %#",
searchText];
self.searchedMemberNameResults = [self.listedMembers filteredArrayUsingPredicate:resultPredicate];
firstName is attribute of an object
Below you can find code for searching an item based on the label in the storyboard. It searches dynamically; I've tested this and it's working.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"job_id contains[c] %#",searchText];
searchResultArray = [responceArray filteredArrayUsingPredicate:resultPredicate];
[jobsTable reloadData];
}

UITableView dataSource must return a cell from tableView: cellForRowAtIndexPath

I have set up a UIViewController with a table view and cell added. The delegate and data source are linked to the table view. However I getting this error and I am confused as to why. The code works when I use it with a UITableViewController but not with a UIViewcontroller. The reason for wanting to use a UIViewController is that the navigation bar scrolls with the table when using a UITableViewController and I was advised on here to use a UIViewController and add the Table view.
#import "ObViewControllerObservationsTable.h"
#import "ObAppDelegate.h"
#import "Observations.h"
#import "ObViewControllerTableDetail.h"
#import "ObViewControllerMainMenu.h"
#interface ObViewControllerObservationsTable ()
#property (nonatomic, strong) NSArray *teacherNames;
#property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *detailsButton;
#end
#implementation ObViewControllerObservationsTable
- (void)viewDidLoad
{
[super viewDidLoad];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Observations"];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"obsTeacherName" ascending:YES]];
NSError *error = nil;
self.teacherNames = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
[self.tableView reloadData];
}
- (NSManagedObjectContext *) managedObjectContext
{
return [(ObAppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.teacherNames.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"teacherCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Observations *currentList = [self.teacherNames objectAtIndex:indexPath.row];
cell.textLabel.text = currentList.obsID;
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self.teacherNames objectAtIndex:indexPath.row]];
[self.managedObjectContext save:nil];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Observations"];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"obsTeacherName" ascending:YES]];
NSError *error = nil;
self.teacherNames = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (self.teacherNames.count == 0)
{
self.detailsButton.enabled = NO;
}
else
{
self.detailsButton.enabled = YES;
}
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
obsID = [[self.teacherNames objectAtIndex:indexPath.row] obsID];
self.detailsButton.enabled = YES;
}
dequeueReusableCellWithIdentifier: returns nil if no reusable object exists in the reusable-cell queue. (See UITableView reference).
Here is how it should be:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"teacherCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// More initializations if needed.
}
Observations *currentList = [self.teacherNames objectAtIndex:indexPath.row];
cell.textLabel.text = currentList.obsID;
return cell;
}
I think the problem is the dequeueReusableCellWithIdentifier method. I tried a quick sample project with a tableView in a view controller rather than in a UITableViewController and encountered the error you describe. When I manually generated the cell using
[UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"testCell"];
it worked fine.

uitableview searchbar ios5 ARC/storyboard

edit: I think the problem is in the last referenced code, because when I try to load the table data instead of the search results (by just swapping the arrays) I still get no search results, but I'm still not sure why... Original post in full:
I'm trying to get a search bar working with my table view. I can enter text in the search bar but always find no results. Here's my .h
#interface SecondViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate> {
IBOutlet UISearchBar *searchBar;
NSMutableArray *dummyArray;
NSMutableArray *searchArray;
}
#property (nonatomic, strong) NSMutableArray *dummyArray;
#property (nonatomic, strong) NSMutableArray *searchArray;
#property (nonatomic, strong) NSMutableArray *detailArray;
#property (nonatomic, strong) NSMutableArray *imageArray;
- (void) setupArray;
- (void) setupSearchArray;
- (void) setupDetailArray;
#end
In my .m, dummyArray is the array that fills the main cell.textLabel.text and the array i want to search.
I set up searchArray here:
- (void) setupSearchArray{
searchArray = [NSMutableArray arrayWithCapacity:[dummyArray count]];
}
then attempt to make searchArray a filtered version of dummyArray here:
- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[searchArray removeAllObjects] ;
for (NSString *savedSeachTerm in dummyArray) {
NSRange result = [savedSeachTerm rangeOfString:searchString options:
NSCaseInsensitiveSearch];
if (result.location != NSNotFound)
[searchArray addObject:savedSeachTerm];
}
return YES;
}
and try to populate the table with search results when search text is entered here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [detailArray objectAtIndex:indexPath.row];
}
else {
cell.textLabel.text = [dummyArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [detailArray objectAtIndex:indexPath.row];
}
if (indexPath.row == 0) {
cell.imageView.image = [UIImage imageNamed:#"row0.png"];
}
return cell;
}
What have I done wrong? Thanks for looking!
I had forgotten to
[self setupSearchArray];
sorry!

Resources