I'm making a tableview with multiple row selected option. So, I used the checkmark accessory type action. I also require to edit/rename the text in the selected row.
Basically, I need to put checkmark (checkbox) on the left side and detail disclosure on the right side of the cell, both functional.
Below code is for checkmark that i have, currently checkmark appears on the right side of the cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
TSIPAppDelegate *appDelegate = (TSIPAppDelegate *)[[UIApplication sharedApplication]delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
appDelegate.selectedFile = cellText;
if (prevSP!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prevSP inSection:0]];
cell.accessoryType=UITableViewCellAccessoryNone;
prevSP=indexPath.row;
}
}
else if (prevSP!=indexPath.row){
cell.accessoryType=UITableViewCellAccessoryNone;
}
}
Any suggestions, please?
When a row selected, checkmark should be enabled/disabled AND disclosure button selected, it should open a new view for editing the selected row.
accessoryType type is of enum UITableViewCellAccessoryType, by definition it will not accept multiple values as it not bitwise enum. So, you have to choose one and mimic the other by custom code.
I'd recommend using the UITableViewCellAccessoryCheckmark accessory type on the tableview and adding a "Detail Disclosure" button to the cell. Unfortunately you can't do exactly what you're looking for, but this is the cleanest alternative approach that I've found.
This is sample code which i have used in one of my app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text=[NSString stringWithFormat:#"%#",[cellarray objectAtIndex:indexPath.row]];
cell.textLabel.textColor=[UIColor blackColor] ;
cell.textLabel.tag=indexPath.row;
cell.textLabel.font=[UIFont fontWithName:#"HelveticaNeue-Bold" size:15];
// cell.textLabel.highlightedTextColor=[UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] ;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
UIImageView *ima=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"tick.png"]];
ima.frame=CGRectMake(280, 15, 14, 14);
ima.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin;
int row = [indexPath row];
//cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
if (row==selectedRow) {
[cell.contentView addSubview:ima];
}
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Background.png"]];
[tempImageView setFrame:tableView.frame];
tableView.backgroundView = tempImageView;
[tempImageView release];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedRow = [indexPath row]; // selected row is of type int declared in .h
[tableView reloadData];
}
This code will have only one checkmark in entire tableView.. You can modify it to have multiple checkmark in that
Hope this helps !!!
Related
I am trying to change the color of a button when pressed that is in a tableviewCell. However my code changes the color of every button in the table and not just the one in the cell I selected,
How would I go about just changing the color of the button I pressed.
Please see my code below,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Test";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];/
[addNotesButton addTarget:self action:#selector(addNotes :) forControlEvents:UIControlEventTouchUpInside];
}
The main issue might be in your cellForRowAtIndexPath: method. UITableView cells are re-used as they are displayed on the screen. dequeueReusableCellWithIdentifier: method returns a cell if it has been marked as ready for reuse. You must have seen this method of UITableView being used in cellForRowAtIndexPath: method. (See this link)
So in cellForRowAtIndexPath: you will have to configure each cell as it is being loaded or else it will display old values (since the cells are being reused).
You can either declare a property or a simple variable of type NSIndexPath.Let the variable be called _selectedIndexPath. Then in didSelectRowAtIndexPath: you can assign this property to the indexPath selected.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSArray *indexPaths = nil;
if (_selectedIndexPath) {
indexPaths = #[_selectedIndexPath, indexPath];
} else {
indexPaths = #[indexPath];
}
_selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
- (void)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Your Cell Identifier"];
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];
if (indexPath.row == _selectedIndexPath.row) {
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
} else {
[addNotesButton setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
}
}
You don't need to change color manually in did select row at index path. Just set the color for UIControlStateSelected and on the action of button tap set the buttons selected property to YES. From your code i think this should work.
inside cell for row at index path method
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
and in button action method
-(IBAction)addNotes:(id)sender
{
UIButton *button = (UIButton*)sender;
buttons.selected = !button.isSelected;
}
I think this will work.
After trying everything and failed. I ended up having a hidden value in each row that would change when the button is pressed. So the code reads the value then configures the button for each row.
As soon as the table view gets touched the cell titles (and on-tap actions) disappear. I only use standard table view cells and store the values in an array. After the values disappear the table stays scrollable. Any ideas?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.textLabel.text = [[systeme objectAtIndex:indexPath.row] description];
cell.backgroundColor = [UIColor clearColor];
[cell.textLabel setTextColor:[UIColor whiteColor]];
[cell.textLabel setTextAlignment:NSTextAlignmentCenter];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:#"choseSystem" object:[systeme objectAtIndex:indexPath.row]];
}
You should be sure that the reuse identifier is the same for all cells if you use only one type of cells. You should do something similar to the following in the portion of your code where to retrieve a reusable cell:
NSString *CellIdentifier = [NSString stringWithFormat:#"CellReuseIdentifier", (long)indexPath.section];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
And make you you set the #"CellReuseIdentifier" in your xib file or your storyboard.
If you would like to use multiple custom cells for a table view you should do something similar to what you're doing, but take into account that reuse identifiers need to be configured for every type of cells.
Hope this helps!
The table view was fine. I just added its view as a subview to another view without keeping reference to the actual UITableViewController. That was the problem.
I am currently trying to give user the ability to edit the content of the multiple cells. Once updated, the data will be sent to web service.
Ok right now, as far as I have read, there is only "delete" and "add" row(s). I can't seem to find any guides or tutorials on how to edit the content of cell(s).
Your suggestion(s) and/or advices are much appreciated.
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
You can not edit cell content directly. If you need to edit content then add UITextField or UITextView in cell as its subview. and then access them.
EDIT : You can add textfield as below :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// ADD YOUR TEXTFIELD HERE
UITextField *yourTf = [[UITextField alloc] initWithFrame:CGRectMake(0, 5, 330.0f, 30)];
[yourTf setBackgroundColor:[UIColor clearColor]];
yourTf.tag = 1;
yourTf.font = [UIFont fontWithName:#"Helvetica" size:15];
yourTf.textColor = [UIColor colorWithRed:61.0f/255.0f green:61.0f/255.0f blue:61.0f/255.0f alpha:1.0f];
yourTf.delegate = self;
[cell addSubview:yourTf];
}
// ACCESS YOUR TEXTFIELD BY REUSING IT
[(UITextField *)[cell viewWithTag:1] setText:#"YOUR TEXT"];
return cell;
}
Implement UITextField delegates and then you can edit cell content using this UITextField.
Hope it helps you.
I want to create a view like this in my iPhone App:
I do not know exactly what is this control in iOS, that maybe I can set an icon and text in the left side and that small sign in the right side.
I have implemented a TableView, there I was able to set these stuff, like this:
[[cell textLabel] setText:customer.name];
[[cell textLabel] setTextColor:[UIColor blackColor]];
[[cell imageView] setImage:[UIImage imageNamed:#"icon.png"]];
//[[cell detailTextLabel] setText:#"Awsome weather idag"];
cell.accessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
But how can I make it works like that view in the picture?
It is pretty simple, follow the steps below and in case of doubts check out the UITableView documentation:
1. Create a grouped table view:
Programmatically:
CGRect tableFrame = CGRectMake(0, 0, 200, 200);
UITableView *tableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewGroupedStyle];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
Allocating a UITableViewController subclass (common case):
MyTableViewController *controller [[MyTableViewController alloc] initWithStyle: UITableViewGroupedStyle];
[self.navigationController pushViewController:controller animated:NO];
Through Interface Build:
Expand the Utilities Menu (top right corner icon);
Select your table view (click on it);
Click on the attributes inspector (top right corner fourth icon);
Under Table View, click on the style dropdown and select grouped.
2. Implement the UITableViewDataSource protocol:
Basically add this three functions to your controller.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in a given section.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cells.
return cell;
}
3. Configuring the cells:
The default style of a UITableViewCell has an image view (UIImageView), a title label (UILabel) and an accessory view (UIView). All you need to replicate the table view in the image you provided.
So, you're looking for something like this in tableView:cellForRowAtIndexPath::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const cellIdentifierDefault = #"default";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierAccount];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierAccount];
}
if (indexPath.section == 0) {
cell.imageView.image = [UIImage imageName:#"bluetooth_icon"];
cell.textLabel.text = #"Bluetooth";
// Additional setup explained later.
}else{
if (indexPath.row == 0) {
cell.imageView.image = [UIImage imageName:#"general_icon"];
cell.textLabel.text = #"General";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}else{
cell.imageView.image = [UIImage imageName:#"privacy_icon"];
cell.textLabel.text = #"Privacy";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
return cell;
}
The property accessoryType defines what is going to appear on the right side of a cell, a list of accessory types can be found here.
In the first cell (bluetooth), you'll need to create a custom accessory view and assign it to the cell's accessoryView property. A very naive example of how to achieve this is given below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const cellIdentifierDefault = #"default";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierAccount];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierAccount];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
label.textAlignment = NSTextAlignmentRight;
cell.accessoryView = label;
}else{
label = (UILabel *) cell.accessoryView;
}
cell.imageView.image = [UIImage imageName:#"bluetooth_icon"];
cell.textLabel.text = #"Bluetooth";
label.text = #"Off";
return cell;
}
Hope this helps, Mateus
For fast output, you can use some library like
https://github.com/escoz/QuickDialog
protip, in my experience, solutions like this leaves you more tangled when Changes come in.
Some times you only want to change one specific label on once specific view, thats not gona be easy in any ready-made solution.
Look into UITableView Sections. That is what separates the groups apart.
I have a custom cell in TableView and there is a button in the cell. When I select the cell, the background turns to blue and the button disappears. Is there any way to prevent this?
The cellForRowAtIndexPath like this -
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MyTableCell *cell = (MyTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[MyTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
Search *current = [self.retrievedTweets objectAtIndex:indexPath.row];
cell.textLabel.text = current.text;
cell.textLabel.font = [UIFont systemFontOfSize:15.0];
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.text = current.name;
cell.imageView.image = current.userImage;
btnUncheck =[[UIButton alloc] initWithFrame:CGRectMake(400, 35, 20, 20)];
btnUncheck.backgroundColor = [UIColor redColor];
btnUncheck.layer.cornerRadius = 10;
btnUncheck.hidden =NO;
btnUncheck.tag=indexPath.row;
//[btnUncheck addTarget:self action:#selector(didSelectRowAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:btnUncheck];
return cell;
}
use custom image for selected table cell. or try with buttons images.
paste below line in your tableview Delegate Method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
///// your code ///////////
cell.selectionStyle=UITableViewCellSelectionStyleNone;
//// your code////////
}
here your blue backgound will not display..
What you can do is this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{[tableView deselectRowAtIndexPath:indexPath animated:YES];}
Hope this helps
Also, if you have already implemented this, what else do you have in this delegate method?
Instead of this line:
btnUncheck = [[UIButton alloc] initWithFrame:CGRectMake(400, 35, 20, 20)];
use:
btnUncheck = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
[btnUncheck setFrame:CGRectMake(400, 35, 20, 20)];
Create a "custom" view with background color clear and set to it.
UIView* vista=[[[UIView alloc] init] autorelease];
vista.backgroundColor=[UIColor clearColor];
cell.selectedBackgroundView=vista;
The way to fix this right, is to create a custom cell that you then add a button to in the xib editor.
So, in xib editor, add a 'UITableViewCell' item. Then add the button to that cell item in the xib editor. You'll then attach your custom cell to the table in the corresponding .m file here:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I have tried this out with just a one row table and the custom cell tied as a property from the xib to the .h file that has the table view. The highlight is there and just grays out the button (still viewable). To get this to work with more rows is more involved. You'll need to load the custom utableviewcell xib and alloc your custom cell dynamically for that to work.