Add subviews according To UITableViewCell CGRect - ios

I'm trying to add subviews to a view according to the cell of the tableview .. i've done this code already
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
VerseCell *cell = (VerseCell *)[tableView cellForRowAtIndexPath:indexPath];
rowSelected = indexPath.row;
CGRect cellRect = cell.frame;
UIView *cellView =[[UIView alloc]initWithFrame:CGRectMake(cellRect.origin.x+4, cellRect.origin.y+15, cellRect.size.width-20, 70)];
UIImageView* background =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"FavoritePanelBackground"]];
background.frame =CGRectMake(cellRect.origin.x+4, cellRect.origin.y+15, cellRect.size.width-20, 70);
[cellView addSubview:background];
[cellView setBackgroundColor:[UIColor redColor] ];
UIButton * favoritsB = [[UIButton alloc]initWithFrame:CGRectMake(cellRect.origin.x+10, cellRect.origin.y+15, 60, 40)];
[favoritsB setBackgroundImage:[UIImage imageNamed:#"MofadalatNormalIcon.png"] forState:UIControlStateNormal];
[favoritsB setBackgroundImage:[UIImage imageNamed:#"MofadalatTappedIcon.png"] forState:UIControlStateHighlighted];
[favoritsB addTarget:self action:#selector(favorite) forControlEvents:UIControlEventTouchUpInside];
[cellView addSubview:favoritsB];
cellView=nil;
}
the problem is .. that this code work as expected in the first row only.. and when click on next cell it shows the main UIVIew (which i've mark with red background) in the expected position while the sub views of it is going really far down... so what i'm doing wrong here.. and is there another approach for what i'm doing if that will not work?

Where are you trying to add these view? Inside the table view cell? If so, you never add cellView as a subview of cell. IF that's what you're trying to do, add this line just above cellView = nil:
[cell addSubview:cellView];

Related

Keep UITableViewCell accessory on top

I have a UITableViewCell with a accessorytype detail indicator. When I resize the cell, the cells accessory centers itself horizontally. How can I make it stay on top, and not center itself?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellID" forIndexPath:indexPath];
return cell;
}
I'd prefer doing it in the storyboard if possible, if not, I'm happy to hear how to do it programatically.
My mistake, Actually you can't do any change in default accessoryView of tableView, You need to create a custom accessoryView for your cell. Just ignore the accessory type because it will not longer matters once you create your own accessoryView.
try this code in CellForRowAtIndexPath
if(!cell.accessoryView)
{
UIImage *image = [UIImage imageNamed:#"image.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
//add target if necessary
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
//apply customisations
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
}

Button added to tableview cell appears on other random cells as well

I'm experiencing a problem with regards to adding a button to a tableview cell. Basically, I'm adding a button to a specific cell, but that button also appears on random other cells (not currently in the view).
When I tap a cell, I set a variable (tappedCell=indexPath), and reload that cell. In my cellForRowAtIndexPath I check if the indexPath is equal to the tappedCell, and if it is I add a button to it. That works, but this button also appears on other cells further down in the tableView. These cells are not in the view when I tap it, but further down, so I have to scroll to see them. If I keep scrolling up and down (quickly), more and more cells with buttons appears. This seems to be completely random.
I've tried adding a NSLog() inside the if-statement where I add the button, but this is not called more than once (when I tap the original cell). So it's actually not adding more buttons, it has to be the same one appearing in multiple cells.
I have no idea why this is happening. I've tried adding a button to every cell, and then just set hidden = YES as standard, and hidden = NO when the [self.tappedCell isEqual:indexPath], but this does not change anything...
Here you can see the code I use to add the button to my cell:
UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[newBtn setImage:[UIImage imageNamed:#"open.png"] forState:UIControlStateNormal];
[newBtn setFrame:CGRectMake(220, 0, 100, 86)];
[newBtn addTarget:self action:#selector(openImage:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:newBtn];
I don't know what I'm doing wrong, or if I am doing something wrong at all. It's worth mentioning that I'm using a standard Apple/iOS style=subtitle cell, and not a custom one. This is to keep it consistent throughout my app (The cells are made in the storyboard, and I'm reusing a prototype cell).
Could anyone give me any insight on why it's behaving like it does, and how I can fix it?
Thanks in advance!
EDIT 1:
Here's my full code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up the item
XYZItem *item = [self.itemsInView objectAtIndex:indexPath.row];
NSString *CellIdentifier = #"itemPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = item.itemName;
if ([self.selectedItem isEqual:indexPath])
{
cell.textLabel.numberOfLines = 2;
UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[newBtn setImage:[UIImage imageNamed:#"open.png"] forState:UIControlStateNormal];
[newBtn setFrame:CGRectMake(220, 0, 100, 86)];
[newBtn addTarget:self action:#selector(openImage:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:newBtn];
}
NSString *detailTextLabelText = [NSString stringWithFormat:#"%lu subitems", (unsigned long)[item.subItems count]];
cell.detailTextLabel.text = detailTextLabelText;
return cell;
}
The button is showing up on cells that have reused a button that previously added it.
There are a few options here.
Make the button part of every cell. Set it's .hidden property every time you create/reuse one to the appropriate value.
Remove the button in the cell's prepareForReuse method.
Assuming self.tappedCell is a UITableViewCell subclass and indexPath is an index path, [self.tappedCell isEqual:indexPath] will always return NO
I faced same issue and i also had multiple headers:
The solution is:
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
headerLabel = [[UILabel alloc] initWithFrame:
CGRectMake(15, 5, self.tableView.frame.size.width, 15.0)];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.textAlignment = NSTextAlignmentLeft;
[headerLabel setFont:[UIFont fontWithName:#"Helvetica Neue Medium" size:13.0]];
headerLabel.tag = 1002;
[cell.contentView addSubview:headerLabel];
button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, HEIGHTROW)];
[button addTarget:self action:#selector(eventAddAlert) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"add_manually.png"] forState:UIControlStateNormal];
button.hidden = YES;
button.tag = 1001;
[cell.contentView addSubview:button];
}else{
// use viewWithTag to find lblNombre in the re-usable cell.contentView
headerLabel = (UILabel *)[cell.contentView viewWithTag:1002];
button = (UIButton *)[cell.contentView viewWithTag:1001];
}
if(indexPath.section == 0 && indexPath.row == 0){
button.hidden = NO;
}else{
button.hidden = YES;
.........
}
.........

UITableViewCell using QuickDialog : handle touch event on all the cell's surface

I use custom cell on UITableView using QuickDialog
In this custom cell I have several UILabel, UIImageView and a button which has the cell size and display on the top of the others subviews.
I want this button handle touch envent and call a selector. But even though the button is at the top position, the touch event does not trigger when I touch a subview.
- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller
{
UITableViewCell *cell = [super getCellForTableView:tableView controller:controller];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = cell.frame;
[btn setEnabled:YES];
[btn setExclusiveTouch:YES];
[btn setBackgroundColor:[UIColor blueColor]]; // To check if the button is at the top position
[btn setStringTag:labelIdText];
[btn addTarget:self action:#selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:label1];
[cell addSubview:label2];
[cell addSubview:image1];
[cell addSubview:image2];
[cell addSubview:btn];
cell.userInteractionEnabled = YES;
return cell;
}
The selector :
- (IBAction)handleTap:(id)sender
{
NSLog(#"CELL TAPPED : \n");
}
Thanks a lot.
EDIT :
New version of the code :
- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller
{
UITableViewCell *cell = [super getCellForTableView:tableView controller:controller];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *top = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[top setStringTag:labelIdText];
[top addGestureRecognizer:singleFingerTap];
[cell.contentView addSubview:label_1];
[cell.contentView addSubview:label_2];
[cell.contentView addSubview:image_1];
[cell.contentView addSubview:image_2];
[cell.contentView addSubview:top];
cell.userInteractionEnabled = YES;
image_1.userInteractionEnabled = YES;
image_2.userInteractionEnabled = YES;
return cell;
}
The selector :
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
NSLog(#"CELL TAPPED : \n");
}
The event is handle when I touch the text containing in the UILabel.
But it's still don't work with the UIImageView despite userInteractionEnabled setted to YES for the images.
Thanks again.
It seams you are assigning to the button the cell frame and then add it to the cell itself. In this way the position of the button is not the one you expect, and even though you can see the button it will not respond to touch because it resides outside the cell bounds.
Try to change this:
btn.frame = cell.frame;
to this:
btn.frame = cell.bounds;
Also when working with UItableViewCell remember to add subviews to its contentView and not the cell itself:
[cell.contentView addSubview:aCustomView];

add multiple horizontal buttons to table view

I've tried a bunch of stuff - adding a button from the object browser, changing attributes, searching the web, but no luck. Essentially, I'd like to do --in the storyboard--:
where you see "add to contacts" "share location" and "add to bookmarks".
You should create a UITableViewCell whose contentView holds 3 separate UIButtons.
To do this programmatically, in your tableView:cellForRowAtIndexPath: data source method, you can use code similar to the following:
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* identifier = #"cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.backgroundColor = [UIColor clearColor];
UIButton* button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton* button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton* button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = UIEdgeInsetsInsetRect(cell.contentView.bounds, UIEdgeInsetsMake(0, 0, 0, 250));
button2.frame = UIEdgeInsetsInsetRect(cell.contentView.bounds, UIEdgeInsetsMake(0, 125, 0, 125));
button3.frame = UIEdgeInsetsInsetRect(cell.contentView.bounds, UIEdgeInsetsMake(0, 250, 0, 0));
button1.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
button2.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
button3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[cell.contentView addSubview:button1];
[cell.contentView addSubview:button2];
[cell.contentView addSubview:button3];
}
return cell;
}
Also, in the tableView:willDisplayCell: method of your delegate, do the following to have the default decoration of the cell totally disappear:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundView = nil;
}
You should obtain a result very similar to what you posted.
Put the three buttons in a UIView that is 320 pixels wide and say 60 hight, and make that view the footer of your table.
The UITableView is styled using the UITableViewStyleGrouped stye.
The three UIButtons are programmatically added to the tableView.tableFooterView.
Alternatively, you can add three UIButtons to the contentView of the last cell.
Add buttons like:
UIButton *theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
theButton.frame = CGRectMake(20, 20, 200, 40);
[theButton setTitle:#"Button" forState:UIControlStateNormal];
[theButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:theButton];
Get the button positions correctly using trial and error :)

Button in UITableview modify current cell custom

I not find a solution to modify my custom cell since a button which is inside. I will wish to change the label text when I click the button.
- (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:nil];
}
// View
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 250)];
[view setBackgroundColor:[UIColor colorWithWhite:255.0 alpha:0.0]];
// Label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320-7-7, 16)];
[label setText:#"Hello"];
[label setTextAlignment:UITextAlignmentLeft];
[label setTextColor:[UIColor grayColor]];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:16]];
[label setBackgroundColor:[UIColor clearColor]];
[view addSubview:label];
// Action
UIButton *action = [[UIButton alloc] initWithFrame:CGRectMake(306-54, 0, 54, 54)];
[action setTitle:#"0" forState:UIControlStateNormal];
[action addTarget:self action:#selector(actionMore:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:action];
// Add view to cell
[cell addSubview:view];
return cell;
}
Edit (add details)
- (void)actionMore:(id)sender{
UIButton *button = (UIButton *)sender;
// Edit current cell, but I do not know how...
}
Thanks.
You can get the cell in which the button was pressed with following lines of code
UITableViewCell * cell = (UITableViewCell*)[[sender superview] superview];
Then use the cell reference to change the label text
cell.yourlabel.text = #"New Text";
Update
I think the above code may not work in iOS 7. The better way is
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.mainTable];
NSIndexPath *indexPath = [self.mainTable indexPathForRowAtPoint:buttonPosition];
Since your UIButton and UILabel are subviews of the same view, you can tag your label, and use viewWithTag to find it from your button's action code:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320-7-7, 16)];
label.tag = 1234;
....
- (void)actionMore:(id)sender{
UIButton *button = (UIButton *)sender;
UILabel *label = [[sender superview] viewWithTag:1234];
// Edit current cell
}
To help you need to give some more details.
Is this a single cell or is it a prototype for multiple?
The code in the actionMore: selector.
What are you trying to do this for? Why a button in a cell to change the label text?
If this cell is being used more than once, a problem could be actionMore: can't isolate which cell is the target for the code. Also you could have a simple typo in the actionMore method but we can't solve that without being able to see all of the interacting code.
If you can provide more details, some one may be able to help. I will edit this answer if I can help you once I have more information.
--EDIT--
First to get cell you can use:
UITableViewCell * cell = (UITableViewCell*)[[sender superview] superview];
Then you can access your cells label by:
cell.label.text = #"Some Text Here";
Your next issue is figuring out where in the list your cell lies. For that use this code:
UITableView * table = (UITableView*)[[[sender superview] superview] superview];
NSIndexPath * indexPath = [table indexPathForCell: cell];
You then can then use a switch statement or if-else statements to find which row was triggered.
- (void)actionMore:(id)sender{
UITableViewCell * cell = (UITableViewCell*)[[sender superview] superview];
UIView *view = [cell.subviews objectAtIndex:0];
UILabel *label = [view.subviews objectAtIndex:0];
[label setText:#"test"];
}
you better add view as a subview of the contentview
pass the indexpath to actionMore or fetch it from there. once you got the indexpath, you are in business.
you may want to set a tag for your textlabel for fetching it from its superview.

Resources