UIButton not getting focus in uitableviewcell - ios

I have custom cells with different buttons created, the buttons are always calling their actions correctly but my problem is that if I click quickly on a button, it does not highlight but is calling its action like I said before. I need to click slowly for a few seconds (1-2 seconds) to see the highlighted state. I think it could be because first of all it's taking the focus of the scrollview of the tableview but I don't know how to fix this problem.
Please help!

Try this code : Make the cell selection type none
- (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];
}
// Configure the cell...
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}

Related

Parse custom tableview cell

I am trying to make a custom tableview cell for an iPad app, using the Parse framework. When i query without the custom cell, it works fine, but as soon as i am changing the cell identifier, i am just stuck at the loading icon.
The code goes as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"specielCelle";
sagerCelle *cell = (sagerCelle *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[sagerCelle alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell
cell.lblPolice.text = [object objectForKey:#"police"];
//cell.textLabel.text = [object objectForKey:self.textKey];
//cell.imageView.file = [object objectForKey:self.imageKey];
return cell;
}
Here my advices,(By the way the question is not clear)
Firstly change your identifier with an indexpath.Row
NSString *cellIdentifier=[NSString stringWithFormat:#"CELL_%d",(int)indexPath.row];
Second
if you are changing your existing cell then you are not be able to go inside of the block of
if(cell==nil)
because your cell is not nil. Write else condition.
Hope it helps.

UITableViewCell Reusing Dobut

I have this little doubt about reusing UITableViewCell.
When we create UITableViewCell it kinda looks like following.
- (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];
[self configureCell:cell forIndexPath:indexPath];
}
}
- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {/**Cell Config Code Goes Here**/}
}
So in my case, every cell in UITableView is different. And if UITableView reuses the cell the cell content is completely different.
Is it good practice to just pass CellIdentifier as nil so every time new cell is created instead given the condition that all cells are different ?
Or should I just move [self configureCell:cell forIndexPath:indexPath]; out and handle it on by my own ?
Cell reusability has its sense if you are using cell contents(same subviews) multiple time. Like you have two lables in your tableViewcell for all rows in your tableView. If you have small number of different cells. like if you have three types of cells to use multiple times in your tableView, you can use cell reusability with 3 different cell identifier.
But if you have all different cell, then its fine if you skip cell reusability.
The proper way of using reusability of the tableView is shown below.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"FollowerCell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell forIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {/**Cell Config Code Goes Here**/}
}
The basic idea of reusability is that every time the similar type of cell should not be created, instead they should be reused just by updating their content.
What happens behind the scene is that there is a queue created in which these similar cells are added. Now Suppose there are 200 rows with different data but only 10 rows are visible. That in the queue only approx 14 cells will be present. Now as you will scroll the tableview up or down, this condition
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
checks wether the queue contains any cell, if yes a cell is fetched from the queue. Also the cells, which were earlier visible now on disappearing are added into the queue. This way everytime instead of new cells are created, the already created cells are used.
Now if you forcely make the cell = nil, than every time new cells will be created and added in the queue. Now if there are 200 data than queue will be containing 200 cells thus resulting in increase in memory size.
Hope it will help you in understanding the tableView. Happy Coding :)
I am afraid you have to move the configure cell code out of if condition to make every cell has its own content.
- (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];
}
[self configureCell:cell forIndexPath:indexPath];
}
While we saying reuse of UITableViewCells, we mean that we don't have to create the UIView hierarchy inside the cell every time. But you need to configure the content for different cells. Like cell.titleLabel.text = xxxx.
Meanwhile, you can use multiple reuseIdentifiers for different kind of cells. Or if you only have one such cell, you can define a cell as an attribute instance so that you don't have to create it everytime.

Tableview subtitles on IOS7

I'm trying to add a subtitle to my tableview cells, but they are not displayed.
Where is the mistake?
Is the row
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle]
up-to-date, also with iOS 7?
Best regards
Frank
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"TestA";
cell.detailTextLabel.text = #"TestB";
return cell;
}
This code:
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
will never execute because dequeueReusableCellWithIdentifier: forIndexPath: is guaranteed to allocate a new cell.
Unfortunately, registerClass:forCellReuseIdentifier: doesn't let you specify a UITableViewCellStyle.
Change dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath to simply dequeueReusableCellWithIdentifier:CellIdentifier. This method does not guarantee a cell will be returned.* When it's not, your code will then create a new cell with the style you want.
* - (It will if you're using a storyboard, as rdelmar points out, but that's not the case here.)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = #"Title1";
cell.detailTextLabel.text = #"Subtitle 1";
return cell;
}
I had a similar problem and no solution on the internet worked for me. Turns out I was being an idiot. I'll post my solution just incase someone else experience a similar scenario.
I am assuming that you are using storyboard, have created a prototype and set the style to subtitle
In your storyboards document outline, make sure you select the protoptype cell and select the subtitle. See image:
Now ensure that the label font colour is of a nature that us visible on your background!
Simply subclass UITableViewCell and override
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
with the first line being
[super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
And register your cell class with the table view
[tableView registerClass:[YourCellSubclass class] forCellReuseIdentifier:#"YourCellID"];

UITableView Contents resets when scrolling

I simply don't understand how to fix this from what's out there.
It's fairly simple, I add a UITextField to my UITableViewCell. The user may type in it, then after scrolling it out and back into view the contents will be reset back to its default status.
This is to do with re-using old cells with dequeueReusableCellWithIdentifier right? I just don't understand how to fix it!
Here is my code:
-(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];
}
//Stop repeating cell contents
else for (UIView *view in cell.contentView.subviews) [view removeFromSuperview];
//Add cell subviews here...
}
You don't have to remove the cell contents once it is initialized they are never recreated, they are reused so your code should look like below
-(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];
}
}
And I assume you want to have some controls onto your cell, in this case you can try using CustomCell which creates all the subviews on initializations.
Usually, all your initializations should be in
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//ALL INITS
}
and outside it you should update the values you added into the cell..
You need to set the inputted text back to the textfield, currently with reuse of cells, the textfield clears out the contents. You could try to store the textfield input in an nsstring property and in your cellforrow method, set the textfield text as that string, if the string has a valid value. That way, even on scrolling, the textfield will only display the user input that was stored into the nsstring property from the textfield.
Before You follow my Answer i want to tell you that following code is bad for memory management because it will create new cell for each rows of UITableView, so be careful for it.
But it is better to use, When UITableView Have Limited rows (about 50-100 may be ) then following code is helpful in your case. Use it, if it is suitable for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// Put your code here.
}
/// Put your code here.
return cell;
}
If you have limited rows then this is best code for you.

UITableViewCell initWithStyle:UITableViewCellStyleSubtitle is not working

I'm having an issue in trying to display info in a cell, one on the left and one on the right. I'm aware using initWithStyle with UITableViewCellStyleSubtitle. I use this but it doesn't seem to work.
Here is some sample code:
- (UITableViewCell *)tableView:(UITableView *)ltableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Account Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:Cellidentifier];
}
Accounts *account = [self.fetchedResultsController objectAtIndexPath];
cell.textLabel.text = account.name;
cell.detailTextLabel.text = #"Price";
return cell;
}
I can display cell.textLabel.text just fine, however I cannot get the simple "Price" to be displayed. I've tried different things, such as setting the font size of cell.detailTextLabel.
I've also tried UITableViewCellStyleValue1 as some had suggested in older posts.
Threw NSLog after setting to "Price", shows cell.detailTextLabel as null.
Not sure what I'm doing wrong.
Edit: I found this: cell.detailTextLabel.text is NULL
If I remove if (cell == nil) it works...
That check should be in place, so how do you make it work when using the different styles?
When using storyboards and prototype cells, a cell is always returned from the dequeue method (assuming a prototype with that identifier exists). This means you never get into the (cell == nil) block.
In your case the prototype cell is not defined in the storyboard with the subtitle style, so a subtitled cell is never used, and the detail text label does not exist. Change the prototype in the storyboard to have the subtitle style.
Remove all your code just once you try these lines only and check this will work or not.
-(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]
autorelease];
}
cell.textLabel.text=[Array objectAtIndex:indexPath.row];
cell.detailTextLabel.text=#"Price";
return cell;
}
I see the problem: in your method name, the UITableView variable is named ltableView, not tableView. Change it to tableView.
cell.detailTextLable.text should be cell.detailTextLabel.text. It looks like a simple mis-spelling of label.
All the answers mentioned here are really a workaround i.e. using storyboard.
Here is a way to do it only in code.
Basically instead of registering the identifier for the cell in viewDidLoad do it only once in cellForRowAtIndexPath: method. Also reset cell registered in viewDidLoad __sCellRegistered = 0;
static int _sCellRegistered = 0;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if (__sCellRegistered == 0) {
__sCellRegistered = 1;
NSLog(#"register cell");
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"CellIdentifier"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"CellIdentifier"];
};
if (!cell) {
NSLog(#"dequeue");
cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier" forIndexPath:indexPath];
}

Resources