Hi need to create a table view with only one cell selectable like this img.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"CellWithSwitch"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CellWithSwitch"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont systemFontOfSize:14];
if(indexPath.row == 0)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.textLabel.text = #"Sound Effects";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if(path.row == 0)
{
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
}
if you like only one row selectable you have to manage this in the methods of the table:
in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
you need to implement the selection logic. if you click on a non-selected object, you select it and deselect all others, or only the one that is currently selected (if there is one selected). If you click on a selected object, just deselect it here
dont forget to do [theTableView reloadData];
in case your screen does not update if you change something in the table's content
then to redraw you just ensure that your method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
ensures that the object which is selected is marked somehow. This way you can also do nice things like showing a toggle ON/OFF button or anything you may whish.
Related
I am using tableView but it does not enter in number of sections and number of rows in tableView here is the code
here is the code for number of sections and number of rows.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
Number of Rows in Sections Code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Cell is");
return 1;
}
Cell Values
- (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.selectionStyle=UITableViewCellSelectionStyleNone;
}
MultipleDetailViewsWithNavigatorAppDelegate *appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
cell.textLabel.font=[UIFont fontWithName:#"Helvetica" size:16];
cell.textLabel.textAlignment=UITextAlignmentLeft;
PublishData *theCellData = [appDelegate.publishArray objectAtIndex:indexPath.row];
NSLog(#"Cell is");
cell.textLabel.text =#"Test";
return cell;
}
Have you set datasource and delegate for the table view? I suspect not. Please set it in code or xib and check.
How you are have added table view ?. if you have added using interface builder then set your datasoure for the tableview. If you have added pro-grammatically then set [tableview setDatasoucre:self];
I have a UITableView that is made up of a number of custom UITableViewCells.
When the table didSelectRowAtIndexPath method fires, if the indexPath.row is equal to 2, I want to update a UILabel within the cell at this row.
My thinking was to use something along the following lines;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 2){
myCustomCellView *cell = [self.essentialsTableView cellForRowAtIndexPath:indexPath];
cell.myUILabel.text = #"my text";
[tableView reloadData];
}
}
The problem here is that cellForRowAtIndexPath returns an object of type UITableViewCell, not myCustomCellView.
Can anyone advise how i might access and update properties of cells within the didSelectRowAtIndexPath method?
Define one Bool value say "secondRowIsClicked". Set it to No in your viewWillApper or viewDidAppear function.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 2)
{
secondRowIsClicked = YES;
[tableView reloadData];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Your code
if (secondRowIsClicked == YES)
{
cell.myUILabel.text = #"my text";
}
}
try with bellow code..
myCustomCellView *cell = (myCustomCellView *) [self.essentialsTableView cellForRowAtIndexPath:indexPath];
you can reload UITableViewCell with its indexPath like bellow..
[self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
myCustomCellView *cell = [self.essentialsTableView cellForRowAtIndexPath:indexPath];
UILabel *yourLabel=[cell.contentViews.subviews viewWithTag:indexPath.row+1];
//do whatever you want with your label;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Your code
cell.myUILabel.text = #"my text";
cell.myUILabel.tag=indexpath.row+1;
}
typecast UITableViewCell to your custom cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 2){
myCustomCellView *cell = (myCustomCellView *)[self.essentialsTableView cellForRowAtIndexPath:indexPath];
cell.myUILabel.text = #"my text";
[tableView reloadData];
}
}
you need to upadte the datasoure and den call the reload the tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 2){
//update the array which is used as the data provider in cell for row at index path.
[tableView reloadData];
}
}
myCustomCellView is a subClass of UITableViewCell.
So just typcast the cell
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 2){
myCustomCellView *cell = (myCustomCellView *)[self.essentialsTableView cellForRowAtIndexPath:indexPath];
cell.myUILabel.text = #"my text";
[tableView reloadData];
}
}
More info:
As per Apple coding guide lines do not user class name start with lower case letter
instead of myCustomCellView use MyCustomCellView
In my UITableView, i need to get the event of the user, so when the cell is selected(checked), i put btn_checked.png and when it's unchecked, i put the btn_unchecked.png.
I guess, what i try to do should be in the didSelectRowAtIndexPath method, so this is my code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self->tableContents objectForKey:
[self->sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell* theCell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"btn_unchecked.png"]];
theCell.accessoryView = imageView;
}
My snippet code doesn't work, so the btw_unchecked.png isn't placed when the row is checked, also, i need to get the event of checked/unchecked to place the right image to the right event.
Thanx in advance.
As an example, this code snippet will toggle the cell's checkmark when the cell is tapped. The pattern is to force a selective reload from the table's datasource when the delegate method is invoked.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Dequeue the cell... then:
static NSString *CellIdentifier = #"tvcOEList";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.accessoryType = (cell.accessoryType == UITableViewCellAccessoryNone) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
You can use following code.
[cell.contentView addSubview:imageView];
i hope this will help you..
I have a basic UITableView that I want to enable the Mail.app style check marks while having no selection style. I have the following snippet:
#define UITableViewCellEditingStyleMultiSelect (3)
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleMultiSelect;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
However, this will never display the check marks on selection (although the empty circles are displayed). Any ideas on how to fix it? I know it uses undocumented features but I'd really like to add support for the check marks. My actual example uses a very customized UITableViewCell and I can't enable the selection style!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
if (self.tableView.isEditing) {
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
} else {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
-(UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleMultiSelect;
}
-(IBAction) switchEditing {
[self.tableView setEditing:![self.tableView isEditing]];
[self.tableView reloadData]; // force reload to reset selection style
}
I'm using a UITableView to allow selection of one (of many) items. Similar to the UI when selecting a ringtone, I want the selected item to be checked, and the others not. I would like to have the cell selected when touched, then animated back to the normal color (again, like the ringtone selection UI).
A UIViewController subclass is my table's delegate and datasource (not UITableViewController, because I also have a toolbar in there).
I'm setting the accessoryType of the cells in cellForRowAtIndexPath:, and updating my model when cells are selected in didSelectRowAtIndexPath:. The only way I can think of to set the selected cell to checkmark (and clear the previous one) is to call [tableView reloadData] in didSelectRowAtIndexPath:. However, when I do this, the animating of the cell deselection is weird (a white box appears where the cell's label should be). If I don't call reloadData, of course, the accessoryType won't change, so the checkmarks won't appear.
I suppose I could turn the animation off, but that seems lame. I also toyed with getting and altering the cells in didSelectRowAtIndexPath:, but that's a big pain.
Any ideas? Abbreviated code follows...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:kImageCell];
if( aCell == nil ) {
aCell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:kImageCell];
}
aCell.text = [imageNames objectAtIndex:[indexPath row]];
if( [indexPath row] == selectedImage ) {
aCell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
aCell.accessoryType = UITableViewCellAccessoryNone;
}
return aCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedImage = [indexPath row]
[tableView reloadData];
}
I solved it like hatfinch suggested in his edit. My code sample make sure there's only one row checked but I'm sure you can tweak it if thats not what you need.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int newRow = [indexPath row];
int oldRow = [lastIndexPath row];
if (newRow != oldRow)
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:
lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I had this exact same problem and never solved it.
In the end it was moot for me because I had to listen for changes in the model (the selection could change outwith the user's control if a connection was lost) so I just changed the model and let the notification reload the data, but it didn't look too pretty (it was like a non-animated deselection, but one run loop iteration late!)
I suspect the only way to do it is, as you suggest, keeping a cache of references to the cells themselves. This shouldn't be too messy if you write a UITableViewCell subclass to encapsulate the logic, overriding -prepareForReuse.
Still, not pretty, and if the ringtone guys at Apple had to do it this way, they ought to have pressed the UITableView team harder to fix it!
EDIT:
Well, what do you know?! This is really easy after all. -[UITableView cellForRowAtIndexPath] will give you the actual cells (or nil if they're offscreen) and you can just change the accessoryType.
I have a cleaner way of doing it.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
I'm using this simple and nice working mechanism with reloadRowsAtIndexPaths.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *rowsArray = [NSArray arrayWithObjects:indexPath, selectedIndexPath, nil];
self.selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:rowsArray withRowAnimation:UITableViewRowAnimationNone];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
.... skipped usual code .....
if ([selectedIndexPath compare:indexPath] == NSOrderedSame) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
This will work as desired...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int newRow = [indexPath row];
int oldRow = [lastIndexPath row];
if (newRow == oldRow){
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
lastIndexPath = indexPath;
}
if (newRow != oldRow)
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:index];
oldCell.accessoryType = UITableViewCellAccessoryNone;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
index = indexPath;
}