I've one UITableView with 5 Sections and multiple different rows within each section.
My code for add UISwitch into TableView
switchForNotification = [[UISwitch alloc]initWithFrame:CGRectMake(300, 10, 100, 40)];
[switchForNotification addTarget:self action:#selector(Notification) forControlEvents:UIControlEventValueChanged];
switchForNotification.on = NO;
[cell.contentView addSubview:switchForNotification];
So, it'll add into TableViewCell.But, when I'm scrolling, Table is reloading accordingly with UITableView methods and switch will be added into other cells.
I want to prevent this issue of adding automatically custom controls into cell while scrolling and reloading.
How can I do that ?
Any suggestions will be appreciated.
Thanks in advance.
You can Make one custom cell which contains one UILable ,UISwitch and UIImageview...
Now as per indexpath.row show and hide this subview as per you needs.
Try this code. Add this code in your cellFotRowAtIndexPath
NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews];
for (UIView *subview in subviews)
{
if([subview isKindOfClass:[UIView class]])
[subview removeFromSuperview];
else if([subview isKindOfClass:[UIImageView class]])
[subview removeFromSuperview];
else if([subview isKindOfClass:[UILabel class]])
[subview removeFromSuperview];
else if([subview isKindOfClass:[UISwitch class]])
[subview removeFromSuperview];
}
[subviews release];
What you need to do is have several different instances of UITableViewCell depending on how many different types of table view cell you have.
Each is assigned a reuse identifier.
Then, in cellForRowAtIndexPath, depending on the section or row of indexPath, you dequeue the appropriate cell, set whatever data, and return that.
So, for example, assuming you have three types of cell for switch, image, and other, you would dequeue as follows:
static NSString *kCellReuseIdentifierSwitch = #"SwitchCell";
static NSString *kCellReuseIdentifierImage = #"ImageCell";
static NSString *kCellReuseIdentifierOther = #"OtherCell";
if (indexPath.row == 0)
{
MySwitchCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellReuseIdentifierSwitch forIndexPath:indexPath];
}
else if (indexPath.row == 1)
{
MyImageCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellReuseIdentifierImage forIndexPath:indexPath];
}
else if (indexPath.row == 2)
{
MyOtherCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellReuseIdentifierOther forIndexPath:indexPath];
}
This example assumes iOS 6 or above where cell instantiation is handled for you by the dequeue method.
if (cell==nil){cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier]; }
Related
I am using UITableview cell for listing a set of questions and 2 textfield is for score 1 and score 2 i inputed the score and total showed on a label after that when am scrolling time the inputed data is disappear on the UITableview .Some one please help me to solve this issue and am adding these textfield and label on the view and this view is the subview of cell.contentview
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else{
for (UIView* view in cell.contentView.subviews) {
if ([view isKindOfClass:[UIView class]]) {
[view removeFromSuperview];
}
}
}
text field added as
UIView * vwbackground = [[UIView alloc] init];
[vwbackground setFrame: CGRectMake(5.0, 5.0, [UIScreen mainScreen].bounds.size.width-10, 90)];
vwbackground.backgroundColor = [UIColor whiteColor];
[cell.contentView addSubview:vwbackground];
self.txtfldInPut1.clearButtonMode = UITextFieldViewModeWhileEditing;
self.txtfldInPut1.autocorrectionType = UITextAutocorrectionTypeNo;
self.txtfldInPut1.inputAccessoryView = numberToolbar;
[vwbackground addSubview:self.txtfldInPut1];
This is because data in table cell is keep on changing as per list items when scrolls . This is a feature of cells in table view .
what you need to do is at the time when put enter your score just update that value to the array/dictonary(whatever you have taken) from which you are intially showing your data in the list.
Hope it helps :)
in my cell data is loading but its is all messed up until i scroll down then if i scroll back everything format correctly. so when every i load listing which is uitableview data is messed up and as soon i start scrolling and scroll back up it gets in place and show correctly. please help.
my code
- (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];
}
for(UIView *v in [cell subviews])
{
if([v isKindOfClass:[UILabel class]])
[v removeFromSuperview];
if ([v isKindOfClass:[UIImageView class]])
[v removeFromSuperview];
}
UIView *CellBGView = [[UIView alloc] initWithFrame:CGRectMake(10, 5, cell.frame.size.width-20, cell.frame.size.height-10)];
CellBGView.backgroundColor = [UIColor whiteColor];
UIImageView *divider = [[UIImageView alloc] initWithFrame:CGRectMake(CellBGView.frame.size.width-155, CellBGView.frame.size.height-140, 150, 150)];
divider.image = [UIImage imageNamed:#"icon_alpha.png"];
[CellBGView addSubview:divider];
......
return cell;
}
Here is out put when i open listing and before scrolling table
here is after scrolling everything gets in place
I have a solution for you.
First, create subclass of UITableViewCell (For example, name it DemoTableViewCell)
In initWithStyle method of DemoTableViewCell, add your images and labels to cell.
In cellForRowAtIndexPath, you don't need add or remove images and labels. Just change color or set image for them.
I am adding subview to UITableViewCell i.e
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault` reuseIdentifier:cellIdentifier];
Here _cellBackgroundView belongs to UIView.
[cell.contentView addSubview:_cellbackground];
I want to check by the help of isDescendantOfView if it contains _cellbackground, but I am getting warning.
if (![_cellbackground isDescendantOfView:[cell subviews]]) {
[cell.contentView addSubview:_cellbackground];
}
else{
[_cellbackground removeFromSuperview];
}
references Check if a subview is in a view
Please help
[cell subviews] return array , but you need to give UIView as input parameter for isDescendantOfView: method , try like this it will work
if (![_cellbackground isDescendantOfView:cell.contentView]) {
[cell.contentView addSubview:_cellbackground];
}
else {
[_cellbackground removeFromSuperview];
}
[cell subviews] should be replaced by a object of UIView
I am wondering whether someone has had similar problem that I am experimented lately.
Let me describe you a little bit further about my issue. I have got a UITableViewController where I have designed a set of custom UITableViewCell in the IB. Each UITableViewCell has got different elements like a UIButton, UITextField and UILabel, etc. Obviously, each UITableViewCell has a different identifier.
Once defined all my UITableViewCells, next step is to instantiate the cell on tableView:cellForRowAtIndexPath:. What I do in this method is depending on section and row, I instantiate the different UITableViewCells by dequeueReusableCellWithIdentifier:forIndexPath:.
Everything seems to work perfectly and correctly created on the table, but the problem arrives when I scroll down. At the very top, I have got a UITableViewCell with a UIButton that I have specified with a concrete action to perform when it is clicked. Scrolling down, there are a couple of UITableViewCells with the same format (an UIButton inside with different actions specified).
The problem is, when a click the first button from the bottom side, this button performs the first action that I have defined on the very top UIButton and its own action.
It seems that when uitableviewdelegate creates new cells or reuse them, it nests functionalities from other indexPath instead of the specified indexPath....
Hope that I have explained myself properly.
Thank you in advance.
[EDIT]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] init];
NSLog(#"indexpath value is: %#", indexPath);
if (indexPath.section == 0)
cell = [self buildSection_0:tableView getIndexPath:indexPath];
else if (indexPath.section == 1)
cell = [self buildSection_1:tableView getIndexPath:indexPath];
else if (indexPath.section == 2)
cell = [self buildSection_2:tableView getIndexPath:indexPath];
else if (indexPath.section == 3)
cell = [self buildSection_3:tableView getIndexPath:indexPath];
else if (indexPath.section == 4)
cell = [self buildSection_4:tableView getIndexPath:indexPath];
return cell;
}
-(UITableViewCell *)buildSection_0:(UITableView *)tableView getIndexPath:(NSIndexPath *)indexPath{
NSString *identifier;
UITableViewCell *cell;
if (indexPath.row == 0){
identifier = #"headerCell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
}
else if (indexPath.row == 1){
identifier = #"buttonCell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
UIButton *button = (UIButton *)[cell viewWithTag:3001];
[button setTitle:#"Scan" forState:UIControlStateNormal];
[button addTarget:self action:#selector(scan) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
-(UITableViewCell *)buildSection_3:(UITableView *)tableView getIndexPath:(NSIndexPath *)indexPath{
NSString *identifier;
UITableViewCell *cell;
if (indexPath.row == [[job jobLocations] count]) { // Adding button insert more Locations
identifier = #"buttonCell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
UIButton *button = (UIButton *)[cell viewWithTag:3001];
[button setTitle:#"Add Location" forState:UIControlStateNormal];
[button addTarget:self action:#selector(newLocation) forControlEvents:UIControlEventTouchUpInside];
}
else{ // Showing different Locations
identifier = #"locationCell";
cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
UILabel *label = (UILabel *)[cell viewWithTag:3007];
UITextField *textField = (UITextField *)[cell viewWithTag:3008];
[label setText:[NSString stringWithFormat:#"Location #%ld", (long)indexPath.row + 1]];
[textField setText:[[[job jobLocations] objectAtIndex:indexPath.row] locationType]];
}
return cell;
}
dequeueReusableCellWithIdentifier:forIndexPath will reuse cells that are no longer visible, you may want to implement prepareForReuse on your cell, or reset it after you dequeue it.
[EDIT]
Seeing you added your code, you should remove previous target/actions from the button before adding the new ones, as the old one will still be there if a cell is being reused:
[button removeTarget:self action:NULL forControlEvents:UIControlEventTouchUpInside];
[button addTarget:...
Add a tag to the button that corresponds to the indexPath.row. Then in your button action method, you can determine which button was clicked by looking at the (UIButton *)sender's tag.
My aim is to filter tableview's cells using search bar. The point is i have a button in a custom cell, this button is whether hidden or not it is added to list on the right(this is another uiview)
For instance, i have added one cell using plus button to the right and hide plus button, and filtered using search bar. When i filtered for the cell i have added, it should come with hidden plus button. Since it is already added before filtering.
I have written some code to textDidChange method of the searchBar but still could not do it.
How to achieve this goal?
My tryout code;
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
NSArray *cells = [tableView visibleCells];
for (DoctorListCell *cell in cells)
{
NSLog(#"Cell: %d",cell.plusButton.tag);
if(cell.plusButton.tag==0)
{
[cell.plusButton setHidden:YES];
[tableView reloadData];
}
}
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = TRUE;
filteredListContent = [[NSMutableArray alloc] init];
for (PlannedCustomer* docs in doctorsTable)
{
NSRange nameRange = [docs.customerName rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound)
{
[filteredListContent addObject:docs];
}
}
}
[self.tableView reloadData];
}
Just try to set hidden property of cell in your cellForRowAtIndexpath method after filtering the cells from your filtered list. Or you can set hidden in tableView:willDisplayCell:forRowAtIndexPath:
UPDATED:
If your plus button is a subview then override then set the hidden property in some method in your custom cell class. And then call that method.
Or you can just remove the plus button instead of hiding.
For example:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *nib;
static NSString *cellIdentifier= #"cell";
UITableViewCell *theCell = [self.tblView dequeueReusableCellWithIdentifier:cellIdentifier];
if([theCell.contentView subviews]){
for(UIView *view in [theCell.contentView subviews]){
[view removeFromSuperview];
}
}
if(theCell== nil)
{
nib = [[NSBundle mainBundle] loadNibNamed:#"Your custom cell name" owner:self options:nil];
theCell = [nib objectAtIndex:0];
theCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
UIButton *btn=(UIButton*)[theCell.contentView viewWithTag:101];
if(yourcondition)
//hide button
else
//show button
}