i want to set image on cell .When i select that cell then only i want to pass image on it i have 3 section in tableview,
first section i have 1row.Second section i have 3row and third section i have 1 row so how to call selected image on cell .If i cliked any cell
i try thi code but it working but i am showing lable also with red color if this view appear on cell background then it hide the label bacground red color only i can see text which is coming on that label but label background color i can't see why this happen .
i put this code in cellfor row at indexpath method
UIView *viewSelected = [[[UIView alloc] init] autorelease];
viewSelected.backgroundColor = [UIColor whiteColor];
cell.selectedBackgroundView = viewSelected;
you can accomplish this in didSelectRowAtIndexPath method.....
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
switch ([indexPath.section]) {
case 0:
{
switch ([indexPath.row]) {
case 0:
{
[cell.imageView setImage:[UIImage imageNamed:#"imageName.png"]];
break;
}
break;
}
}
Separate the section using the check
if (indexPath.section == 0){
//perform selection of section 0
}
else if (indexPath.section == 1){
//perform selection of section 1
}
else if (indexPath.section == 2){
//perform selection of section 2
//Also do the selection of particular row
if (indexPath.row == 0){
//perform selection of row 0 section 2
}
}
Related
I need to add button to separate cells
Button in yellow circle
i can add to all cells like [cell addSubview:myButt]; but it works to all cells, i need only for 5, 6, 7, 8 cells;
Do i need to write a custom UITableViewCell?
And that line(black arrows), as i understand it is Section, how can i create it with no title, with line(image) and in middle of the table? Thank's to all.
P.S. Sorry for my English
You can hide your section header like this :
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.0f;
// or 1.0 as per your line
}
For buttons on your cells, you have to create a custom cell Class and then use that in cellForRowAtIndexPath method. You can also use tags for this. You can do it like this:
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:"Cell"];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
if(indexPath.section == 1)
{
if(indexPath.row>=5 && indexPath.row <=8)
{
//adding buttons to custom cell
}
}
}
You could use the tag property of UIView to keep track of your button but I'd really recommend to use a custom UITableViewCell. With that being said, below is the code you could use. It is optimized to not add the same button over and over but just when you need it, and hide it in cases you don't need it.
static int kButtonViewTag = 3294802;
UIButton *button = [cell.contentView viewWithTag:kButtonViewTag];
BOOL shouldDisplayButton = indexpath.row == 5 || indexpath.row == 6 || indexpath.row == 7 || indexpath.row == 8;
// If the button should be displayed and is not
//
if (shouldDisplayButton) {
// Add button here
//
if (!button) {
button = // Init your button
button.tag = kButtonViewTag;
[cell.contentView addSubview:button]
}
else if (button.isHidden) {
button.hidden = NO;
}
}
// If the button should not be displayed but is
//
else if (!shouldDisplayButton && button && !button.isHidden) {
button.hidden = NO;
}
And then for your section:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGFloat tableWidth = tableView.frame.size.width;
CGFloat padding = 10; // Add some padding
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(padding, 0, tableWidth - padding * 2, 1)];
[view setBackgroundColor:[UIColor greyColor]; //your background color...
return view;
}
Just add button in cellforrow method :
If (indexpath.row == 3 || indexpath.row == 4 || indexpath.row == 5 || indexpath.row == 3)
{
// add button here
// tag button here
Button.tag = indexpath.row ;
}
I have a UILabel as subview of my cell. When user highlight a cell the label text change it's color and when the cell is unhighlighted the color changes back, just like an usual cell textLabel.
The problem is that if the user tap a cell and scroll the table the cell will unhighlight, the unhighlight delegate method will be called but it will return [2147483647, 2147483647] as index path and the text will not change, as there is no cell on that index path.
Here is the code:
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath*)indexPath{
NSInteger section = [indexPath section];
//only change the text on cells at section 1
if (section == 1) {
//get cell with given index path
UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath];
// retrieve the UILabel by it's tag
UILabel *cellLabel = (UILabel *)[currentCell viewWithTag:1011];
cellLabel.textColor = [UIColor darkGrayColor];
}
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath*)indexPath{
NSInteger section = [indexPath section];
if (section == 1) {
UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *cellLabel = (UILabel *)[currentCell viewWithTag:1011];
[cellLabel performSelector:#selector(setTextColor:) withObject:[UIColor lightGrayColor] afterDelay:0.2f];
}
}
How can i retrieve the correct cell to change it's UILabel subview text when the user scrolls table with a cell highlighted?
Testing those methods I had the same strange results for the indexPath (no idea, why these methods are not working properly).
But I would suggest to just write your own UITableViewCell subclass and override the following method (that is called every time a cell gets selected/deselected):
- (void) setSelected : (BOOL) selected animated : (BOOL) animated {
[super setSelected: selected animated: animated];
// your customisations to your UILabel
if (selected == NO) {
self.textLabel.textColor = [UIColor lightGrayColor];
}
}
Hope this answer helps you out with your problem
I have a table view that needs a custom UITableViewCellAccessoryCheckmark. The checkmark displays when a row is selected and disappears when anther row is selected and then appears on the last most selected view. That works fine.
the problem arises when I use this line:
cell.accessoryView = [[ UIImageView alloc ]
initWithImage:[UIImage imageNamed:#"icon-tick.png" ]];
to add a custom UITableViewCellAccessoryCheckmark. After that code the UITableViewCellAccessoryCheckmark remain on all rows and don't disappear when another row is touched.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int index = indexPath.row; id obj = [listOfItems objectAtIndex:index];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%d",indexPath.row);
if (rowNO!=indexPath.row) {
rowNO=indexPath.row;
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryView = [[ UIImageView alloc ]
initWithImage:[UIImage imageNamed:#"icon-tick.png" ]];
[self.tableView cellForRowAtIndexPath:lastIndexPth].accessoryType=UITableViewCellAccessoryNone;
lastIndexPth=indexPath;
}
A much cleaner and cooler way would be to overwrite UITableViewCell like this:
- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType
{
// Check for the checkmark
if (accessoryType == UITableViewCellAccessoryCheckmark)
{
// Add the image
self.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"YourImage.png"]] autorelease];
}
// We don't have to modify the accessory
else
{
[super setAccessoryType:accessoryType];
}
}
If you have done that, you can continue using UITableViewCellAccessoryCheckmark because your class will automatically replace it with an image.
You should only set the style in your cellForRowAtIndexPath method. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// [init subclassed cell here, dont forget to use the table view cache...]
cell.accessoryType = (rowNO != indexPath.row ? nil : UITableViewCellAccessoryCheckmark);
return cell;
}
And then, you just have to update rowNO in didSelectRowAtIndexPath to update your data and redraw the cell, like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (rowNO != indexPath.row)
{
rowNO = indexPath.row;
}
[self.tableView reloadData];
}
Also, instead of reloading the whole table with [self.tableView reloadData], you could only reload the two cells that change their style (e.g. checkmark) using reloadRowsAtIndexPaths.
Hm don't know why but i can't add comments so im writing this as answer. The problem with Blauesocke answer is that the AccessoryType wil be not set to UITableViewCellAccessoryCheckmark so you can't check the cell AccessoryType. Is there some way to do it right so the cell AccessoryType will be corect type just another image.
I'm using the method like this :
- (void)setAccessoryType:(UITableViewCellAccessoryType)newAccessoryType
{
[super setAccessoryType:newAccessoryType];
// Check for the checkmark
switch(newAccessoryType)
{
case UITableViewCellAccessoryCheckmark:
self.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"yorCheckmark.png"]];
break;
case UITableViewCellAccessoryNone:
self.accessoryView = nil;
break;
default:
break;
}
}
I am putting together a search string based off 4 tableviewcells, each cell opens a subview and loads a bunch of data the user selects to set the cell of the previous view.
There is an order in which these cells needs to be set so that each preceding list of data in the subview is related to the data set in the parent view.
i.e. in the first cell you select a type of car, in the next cell you look at the models related to the type of car chosen.
That aside The basis of my question is how do I make a cell unselectable until the previous cell/s have been set.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
if (indexPath.section == 0)
{
if (indexPath.row == 0) // <<--- what could I put in here....
{
//...
}
}
}
Disallow the cell to track any interaction:
[cell setUserInteractionEnabled:NO];
or allow interaction, hiding the selection colour, and when clicked, do nothing.
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
- (void) tableViewDidSelectRow.... {
if(indexPath.row == indexOfCellWithNoUserInteraction) {
//do nothing
}
}
Use tableView:willSelectRowAtIndexPath:. Return nil for the rows you don't want selected.
Swift Syntax
cell.selectionStyle = UITableViewCellSelectionStyle.None
I have two tableviews, one has several tableview cells each cell opens the same subview but initalized with new data..
There are around about 100 - 200 entries into the table and I have a accessory view that is a tick that when a cell is selected it ticks the cell then loads the main view again.
If I select that same cell to get the same dataset back it loads the previously selected cell in the middle of the screen (so it knows its index path) however the tick "depending on how deep in the list" will or will not be visible..
It tends to work in about the top 30/40% of the table but anything lower the tick will not be visible... that is unless I go back and forth getting deeper and deeper each time then sometimes I can get the tick to appear in the deeper part of the tableview.. Would anyone know why this is happening?
Has anyone had something of this nature happen to them before?
At further investigation I think something is going wrong inside this method..
First of all, in the subview once the user selects a cell this method is called
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
[self.navigationController popViewControllerAnimated:YES]; //pops current view from the navigatoin stack
//accesses selected cells content
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// now you can use cell.textLabel.text
//This if statment is based off which cell was selected in the parent view so that it knows which cell to pass the data back to
if (parentViewSelectedIndexPath.section == 0) {
if (parentViewSelectedIndexPath.row == 0) {
manufactureCellTextLabel = cell.textLabel.text; //passing label text over to NSString for use with delegate (check "viewwilldissapear")
[[self delegate] setManufactureSearchFields:manufactureCellTextLabel withIndexPath:indexPath]; //This is where I pass the value back to the mainview
}
// a few more If statements for the other methods I can pass data too.
//--- this if block allows only one cell selection at a time
if (oldCheckedData == nil) { // No selection made yet
oldCheckedData = indexPath;
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else {
UITableViewCell *formerSelectedcell = [tableView cellForRowAtIndexPath:oldCheckedData]; // finding the already selected cell
[formerSelectedcell setAccessoryType:UITableViewCellAccessoryNone];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; // 'select' the new cell
oldCheckedData = indexPath;
}
}
This passes Index path over to the main view method...
- (void) setManufactureSearchFields:(NSString *)cellLabeltext withIndexPath:(NSIndexPath *)myIndexPath
{
manufactureSearchObjectString = cellLabeltext;
manufactureResultIndexPath = myIndexPath;
[self.tableView reloadData]; //reloads the tabels so you can see the value.
}
//Which then sets the manufactureResultIndexPath that is used in the next method to pass it back to the subview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
//--- Idendify selected indexPath (section/row)
if (indexPath.section == 0) {
//--- Get the subview ready for use
VehicleResultViewController *vehicleResultViewController = [[VehicleResultViewController alloc] initWithNibName:#"VehicleResultViewController" bundle:nil];
// ...
//--- Sets the back button for the new view that loads
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style: UIBarButtonItemStyleBordered target:nil action:nil] autorelease];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:vehicleResultViewController animated:YES];
[vehicleResultViewController setDelegate:self];
if (indexPath.row == 0)
{
vehicleResultViewController.title = #"Manufacture";
[vehicleResultViewController setRequestString:#"ID.xml"]; //sets the request string in searchResultsViewController
vehicleResultViewController.dataSetToParse = #"ID"; // This is used to controll what data is shown on subview... logic
[vehicleResultViewController setAccessoryIndexPath:manufactureResultIndexPath]; //sends indexpath back to subview for accessory tick
vehicleResultViewController.parentViewSelectedIndexPath = indexPath;
}
//etc etc
}
And finaly I pass it to the method in my subview that passes the indexpath to oldCheckedData
- (void)setAccessoryIndexPath:(NSIndexPath *)myLastIndexPath
{
oldCheckedData = myLastIndexPath;
[self.tableView reloadData]; //<<---- this is where I reload the table to show the tick...
}
Try moving the cell.accessoryType = lines to the willDisplayCell: delegate function like so:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// You can move this one here too:
cell.selectionStyle = UITableViewCellSelectionStyleNone; // no blue selection
if (indexPath == oldCheckedData) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
I read that the willDisplayCell: method should be used for any basic visual related modifications to a cell like selectionStyle/accessoryType, and the cellForRowAtIndexPath: method for cell data related operations like setting text, images, etc...
I have recently come across this issue, if turned out the in my case the cell has a accessoryview set. This snippet withh ensure the view is removed.
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
..logic here to to determine if cell should be selected...
if ( cell.accessoryView != nil) {
cell.accessoryView?.removeFromSuperview()
cell.accessoryView = nil
}
cell.accessoryType = .checkmark