At the outset I would like to tell that I have researched and tried to follow stackoverflow links such as UISearchDisplayController and custom cell but still the problem persists
I have Search Bar and Search Display controller integrated into my UITableView. The search functionality works fine but the search results cell have the default white cell design and not my custom cell design which is used for the UITableView. Below is my code to make the Search Result's Cell design adapt my custom design.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.searchDisplayController.searchResultsTableView registerClass:[ItemCellTableViewCell class] forCellReuseIdentifier:#"Cell"];
if(!self.document){
[self initDocument];
}
self.filteredItemCatalogArray = [[NSMutableArray alloc]init];
self.itemCatalogTableView.dataSource = self;
self.itemCatalogTableView.delegate = self;
[self.itemCatalogTableView reloadData];
self.itemCatalogTableView.backgroundColor = [UIColor clearColor];
self.itemCatalogTableView.opaque = NO;
self.itemCatalogTableView.bounces = YES;
self.itemCatalogTableView.backgroundView = nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
if(tableView == self.searchDisplayController.searchResultsTableView)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//cell fields customization
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
return cell;
}
else
{
ItemCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//cell fields customization
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
return cell;
}
}
What am I missing here ?
EDITED :
In the if block for search results I changed tableview to self.tableview and it gets the correct custom cell. But it takes the incorrect height which is smaller and so overlaps the rows for search results
In the if block for search results I changed tableview to self.tableview and it get the correct custom cell. But it takes the incorrect height which is smaller and so overlaps the rows for search results
to rectify the height issue I added the following line in viewdidload
self.searchDisplayController.searchResultsTableView.rowHeight =
self.tableView.rowHeight ;
1) If your cell are using a xib file you should add to viewDidLoad (or other method that will be called before tableView delegate)
[yourTableView registerNib:[UINib nibWithtName:#"your_nibName" bunde:yourBunde] forCellReuseIdentifier:#"yourIdentifier"]
also you should use registred identifier for custom cell :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
static NSString *CustomCellIdentifier = #"yourIdentifier";
if(tableView == self.searchDisplayController.searchResultsTableView)
{
// UITableViewCell customization
return cell;
}
else
{
ItemCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier forIndexPath:indexPath];
if (!cell)
cell = [[ItemCellTableViewCell alloc] initWithStyle:yourPreferedStyle reuseIdentifier:CustomCellIdentifier] // or other custom initialization
//put cell fields customization here
return cell;
}
}
If your custom cell is designed using a NIB try this
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"YourCellNibName" bundle:Nil] forCellWithReuseIdentifier:#"Cell"];
You have to get a reference of your tableView and then in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
MyCell *cell = (MyCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
...
}
Related
Trying to get my app to display text in its cells. Been scratching my head for a while. This is the code used to display the text but nothing appears. Any advice?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"leftMenuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.section == 0) {
NSArray *titles = #[#"Quick Glance", #"Your Home", #"Invites"];
cell.textLabel.text = titles[indexPath.row];
}
cell.backgroundColor = [UIColor clearColor];
return cell;
}
If you have not add the following code in ViewDidLoad() method, please do so.
self.tableView.dataSource = self;
self.tableView.delegate = self;
Firstly you should break this out differently so that you are not re-creating your backing store every time you are producing a cell.
More code would be required in order to ascertain exactly what the issue but at minimum you could put the following in to verify this.
#implementation ViewController {
NSArray *_titles;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_titles = #[#"Quick Glance", #"Your Home", #"Invites"];
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return [_titles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"leftMenuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = titles[indexPath.row];
cell.backgroundColor = [UIColor clearColor];
return cell;
}
This is the bare minimum you will need above in order to show some information in the tableview
Now the question is are you using a UITableViewController where it already has set the dataSource and delegate methods or are you using a UIViewController where the dataSource and delegate have not been set (either in code or through XIB or Storyboard)?
If you do not have the delegates set up you need to set them up either through the storyboard or through the code, and if through code and using UIViewController make sure you have a reference to the UITableView otherwise you will not be able to set the datasource.
I am having issues with my tableView not firing the didSelectRowAtIndexPath method. I have implemented the delegates as such:
#interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate,UIScrollViewDelegate>
And in my storyboard the tableView's data source and delegate are both pointed at the base View Controller. I have User Interactions enabled as well as Selection set to Single Selection, and it is not the TapGesture problem since my tap gestures are not bound to the view and I have checked and they do not fire.
This is the code for setting up the table:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return menuArray.count;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"menuCell"];
NSDictionary *menuItem = [menuArray objectAtIndex:indexPath.row];
cell.textLabel.text = menuItem[#"Title"];
cell.detailTextLabel.text = menuItem[#"Subtitle"];
return cell;
}
-(void)showMenu{
[UIView animateWithDuration:.25 animations:^{
[content setFrame:CGRectMake(menuTable.frame.size.width, content.frame.origin.y, content.frame.size.width, content.frame.size.height)];
}];
}
-(void)hideMenu{
[UIView animateWithDuration:.25 animations:^{
[content setFrame:CGRectMake(0, content.frame.origin.y, content.frame.size.width, content.frame.size.height)];
}];
}
-(IBAction)showMenuDown:(id)sender {
if(content.frame.origin.x == 0)
[self showMenu];
else
[self hideMenu];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//whatever
}
The table is initially out of view on the storyboard (origin.x is set to -150), then when the user clicks on a button in the navigationBar, the view slides over to reveal it, which is what might be causing the problem I think.
Is there anything wrong with my code or implementation that would be causing this to not work?
If you already see your table populated with values from your dictionary then you can rule out data source and delegate as being the problem. i.e. your storyboard connections are working.
Your code looks fine to me. the only difference I see is I usually define my table like this. Try this and see if it helps.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(#"Inside cellForRowAtIndexPath");
static NSString *CellIdentifier = #"Cell";
// Try to retrieve from the table view a now-unused cell with the given identifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// If no cell is available, create a new one using the given identifier.
if (cell == nil)
{
// Use the default cell style.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Your code here
// ....
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"menuCell"];
This will return nil in case there was never a cell created.
so checking if cell is nil is mandatory and if so, you need to create a cell.
static NSString *CellIdentifier = #"menuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
as you are using storyboard you can alternatively use
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
for prototype cells. Make sure you use the same identifier in the storyboard and that you registered your the cell's class
- (void) viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"menuCell"];
}
I have a UITableView with CustomCell. The custom cells contain a UILabel and a UIImageView.
I saw online that it is possible to get the text from a normal UITableView cell and store it in a string when the user presses the cell.
But how can you do this when you are using a custom cell? Becuase the name of my UILabel is "type_label" and it has been defined in the header file of my CustomCell XIB.
So in Xcode I can't use:
cell.type_label.text"
In the following function:
-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Thanks, Dan.
In the tableViewDidSelectRow all you need to do is:
UITableViewCellCustomClass *customCell = (UITableViewVellCustomClass*)[tableView cellForRowAtIndexPath:indexPath];
NSString *labelText = [[customCell type_label] text];
That should get you want you need.
Try below code - You have create type_label label's IBOutlet in CCustomCellClass
(file-->new-->subclass--> UITableViewCell-->name it like CustomCellClass)
Then implement below code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Cell";
static BOOL nibsRegistered = NO;
if (!nibsRegistered) {
UINib *nib = [UINib nibWithNibName:#"CustomCellClass" bundle:nil];
[tableView registerNib:nib forCellReuseIdentifier:cellIdentifier];
}
CustomCellClass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomCellClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.type_label.text = #"Rocky"; // setting custom cell label
return cell;
}
i was following this torturial:
http://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients
It covers customization of dynamic table cells, i need to do it with static table cells.
I have given every cell the identifier "Cell", as he does in the tutorial, i then subclassed the table view controller and implemented this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// START NEW
if (![cell.backgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.backgroundView = [[CostumCellBackground alloc] init];
}
if (![cell.selectedBackgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.selectedBackgroundView = [[CostumCellBackground alloc] init];
}
// END NEW
cell.textLabel.backgroundColor = [UIColor clearColor]; // NEW
return cell;
}
CostumCellBackground draws the rect.
I am getting the error "UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
As far as i understand UITableView is looped for every Cell in the storyboard, and it is supposed to return cell.
So, whats going on here and why does the cell return nil, or doesnt return at all ?
The only difference is that they are static tables, and not prototypes.
If you are using Storyboards and iOS6 and your view controller is a UITableViewController, you will always get a cell if your cell identifier is present in your storyboard. Checking for cel == nil is the old way to do it.
Are you sure you have a custom cell in your storyboard with the "Cell" identifier?
Also, use this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
If you look in the UITableView.h file you will find:
// newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
Where is you create your cell ??
You should add after:
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
such code (or something another initializer):
if (cell == nil) {
cell = [[UITableViewCell alloc] init];
}
Try this at the beginning of your method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle: UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier
];
}
In my project I have tableViews with static cells as well as tableViews with dynamic cells. In order to customized I've managed to get a gradient background on the cells (grouped sytle).
It works ok with dynamic TableViews as I set the background view in cellForRowAtIndex... according to the position of the row (Top, Bottom, Middle or single).
However, when I try to implement it on the static tableview cells, it doesn't work. I've tried to implement the cellForRowAtindex... but it crashes.
Does someone have an idea?
Update: the code for cellForRow..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UACellBackgroundView *bgw=[[UACellBackgroundView alloc]init];
if (indexPath.row==0) {
bgw.position = UACellBackgroundViewPositionTop;
cell.backgroundView=bgw;
}else if (indexPath.row==2){
bgw.position = UACellBackgroundViewPositionBottom;
cell.backgroundView=bgw;
}else {
bgw.position = UACellBackgroundViewPositionMiddle;
cell.backgroundView=bgw;
}
// cell.backgroundView=bgw;
return cell;
}
By the way, the Background view I got it from here: http://code.coneybeare.net/how-to-make-custom-drawn-gradient-backgrounds and here: http://pessoal.org/blog/2009/02/25/customizing-the-background-border-colors-of-a-uitableview/
if somebody is interested
It doesn't look like you are alloc the UITablViewCell, you need to alloc the cell.
For example:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// alloc the UITableViewCell
// remeber if you are not using ARC you need to autorelease this cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Cell Name";
cell.detailTextLabel.text = #"Cell Detail";
return cell;
}
Add this statement:
if (cell == nil) {
// alloc the UITableViewCell
// remeber if you are not using ARC you need to autorelease this cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
If you have a UITableViewController subclass with a static table you should not try to dequeue cells.
Instead you should ask super for the cell. The superclass will get the cell from the storyboard and you can configure it.
Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
UIView *selectedBackgroundView = [[UIView alloc] init];
cell.selectedBackgroundView = selectedBackgroundView;
cell.selectedBackgroundView.backgroundColor = [UIColor mb_tableViewSelectionColor];
return cell;
}
Works for all other attributes as well.