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
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.
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 ¡
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];
}
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.
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!