I have a custom UITableview which is diveded into sections, I have implemented UISwipeGestureRecognizer into it. When I swipe my table view cell, a UIButton appears. The problem I am now facing is when I swipe the first table view cell, another cell in successive sections also recognizes the swipe gesture. I am not able to find how to swipe a cell of particular a section without other cells of other sections getting swiped.
I just want to swipe, I don't want to delete/insert or add check marks.
UPDATE.... This is my customCell.m
Tableview = customTableView
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.symptomCellImageView.contentMode=UIViewContentModeScaleToFill;
swipeButton = [[UIButton alloc]init];
swipeButton .frame = CGRectMake(220.0, 8.0, 30.0, 30.0);
swipeButton .hidden = NO;
}
In my MainViewController.m
-(void)viewDidLoad
{
symptomSwipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandleLeft)];
symptomSwipeLeft .numberOfTouchesRequired = 1;
symptomSwipeLeft .direction = UISwipeGestureRecognizerDirectionLeft;
[customTableView addGestureRecognizer:symptomSwipeLeft];
[self addGestureRecognizer:symptomSwipeRight];
symptomSwipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandleRight)];
symptomSwipeRight.numberOfTouchesRequired = 1;
symptomSwipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[customTableView addGestureRecognizer:symptomSwipeRight];
[self addGestureRecognizer:symptomSwipeRight];
}
- (void)swipeHandleLeft:(UISwipeGestureRecognizer *)aSwipeGestureRecognizer
{
CGPoint location = [aSwipeGestureRecognizer locationInView:customTableView ];
NSIndexPath * indexPath = [customTableView indexPathForRowAtPoint:location];
if(indexPath)
{
UITableViewCell * cell = (UITableViewCell *)[customTableView cellForRowAtIndexPath:indexPath];
[cell.swipeButton addTarget:self action:#selector(secondPageButton:) forControlEvents:UIControlEventTouchUpInside];
}
}
- (void)swipeHandleRight:(UISwipeGestureRecognizer *)aSwipeGestureRecognizer
{
CGPoint location = [aSwipeGestureRecognizer locationInView:customTableView ];
NSIndexPath * indexPath = [customTableViewindexPathForRowAtPoint:location];
if(indexPath)
{
UITableViewCell * cell = (UITableViewCell *)[customTableView cellForRowAtIndexPath:indexPath];
[cell.swipeButton addTarget:self action:#selector(secondPageButton:) forControlEvents:UIControlEventTouchUpInside];
}
}
Try:
- (void)handleSwipe:(UISwipeGestureRecognizer *)aSwipeGestureRecognizer; {
CGPoint location = [aSwipeGestureRecognizer locationInView:_tableView];
NSIndexPath * indexPath = [_tableView indexPathForRowAtPoint:location];
if(indexPath){
UITableViewCell * cell = (UITableViewCell *)[_tableView cellForRowAtIndexPath:indexPath];
[cell whateverMethodYouWant];
}
}
As a side note, the reason you are getting calls to multiple cells is because the row is not unique enough. There is a row = 0 in all of you sections. Therefore, if you want each cell to have a unique number attached to its .tag property, you would need to know the largest number of rows in any section (call it largestNumberOfRows), and then compute:
cell.swipeButton.tag = (indexPath.section * largestNumberOfRows) + indexPath.row;
Hope that helps!
EDIT:
To use the above method, in your viewDidLoad; method, add the following code:
UISwipeGestureRecognizer * recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft)];
[_tableView addGestureRecognizer:recognizer];
EDIT 2
Looking at your code, you have put your gesture recognizers in the wrong file. Here is the setup:
In your MainViewController.m file:
- (void)viewDidLoad; {
[super viewDidLoad];
UISwipeGestureRecognizer * recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft)];
[_tableView addGestureRecognizer:recognizer];
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)aSwipeGestureRecognizer; {
CGPoint location = [aSwipeGestureRecognizer locationInView:_tableView];
NSIndexPath * indexPath = [_tableView indexPathForRowAtPoint:location];
if(indexPath){
UITableViewCell * cell = (UITableViewCell *)[_tableView cellForRowAtIndexPath:indexPath];
if(aSwipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionRight){
[cell symptomCellSwipeRight];
}
else if(aSwipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionLeft){
[cell symptomCellSwipeLeft];
}
}
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
// Initial your cell. Then add:
[cell.swipeButton addTarget:self action:#selector(secondPageButton:) forControlEvents:UIControlEventTouchUpInside];
}
In your PPsymptomTableCell.m file:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; {
if((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])){
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.symptomCellImageView.contentMode=UIViewContentModeScaleToFill;
// SHARE ON FACEBOOK BUTTON //
shareFacebookButton = [[UIButton alloc]init];
shareFacebookButton.frame = CGRectMake(220.0, 8.0, 30.0, 30.0);
shareFacebookButton.hidden = NO;
// DISPLAY NOTIFICATION IMAGE //
selectedCellImageDisplay = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"selectedSymptomImage.png"]];
selectedCellImageDisplay.frame = CGRectMake(240.0, 8.0, 30.0, 30.0);
// SYMPTOM NAME //
symptomCellLabel=[[UILabel alloc]initWithFrame:CGRectMake(15.0,0.0 ,280.0,40.0)];
symptomCellLabel.font=[UIFont fontWithName:#"Rockwell" size:17];
symptomCellLabel.textColor=[UIColor blackColor];
symptomCellLabel.backgroundColor=[UIColor clearColor];
[self.contentView addSubview:symptomCellLabel];
[self.contentView addSubview:selectedCellImageDisplay];
[self.contentView addSubview:shareFacebookButton];
}
return self;
}
- (void)symptomCellSwipeLeft; {
[UIView beginAnimations:#"HideView" context:nil];
symptomCellLabel.frame = CGRectMake(-183.0, 0.0, 280.0, 40.0);
selectedCellImageDisplay.frame = CGRectMake(-340.0, 8.0, 30.0, 30.0);
shareFacebookButton.frame = CGRectMake(120.0, 8.0, 80.0, 30.0);
shareFacebookButton.hidden = NO;
shareFacebookButton.backgroundColor = [UIColor redColor];
[UIView setAnimationDuration:0.3f];
[UIView commitAnimations];
}
- (void)symptomCellSwipeRight; {
[UIView beginAnimations:#"HideView" context:nil];
symptomCellLabel.frame = CGRectMake(15.0,0.0 ,280.0,40.0);
selectedCellImageDisplay.frame = CGRectMake(240.0, 8.0, 30.0, 30.0);
shareFacebookButton.frame = CGRectMake(220.0, 8.0, 30.0, 30.0);
shareFacebookButton.hidden = YES;
[UIView setAnimationDuration:0.3f];
[UIView commitAnimations];
}
This should get everything working nicely.
You are implementing your table with sections, then make your tag value of combination of indexPath.sections and indexPath.row.
But make sure you are implementing without overlapping of tagValue.
Related
I made a custom button using drawRect: and put it in my headerview for my tableview. I want the custom button to be hidden when editing mode is selected. i know i can do that by using the method:
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
but for some reason, my button isn't actually dissapearing when I either 1) set it to nil, 2) or use the button.hidden property. Here is my code:
TableViewController.h:
#interface ToDoTableViewController : UITableViewController <Properties2ViewControllerDelegate, UITableViewDelegate>{
addButtonView *button;
}
#property (strong, nonatomic) NSMutableArray *taskArray;
#property (strong, nonatomic) NSMutableArray *completedArray;
-(IBAction)addCell:(id)sender;
-(void)buttonPressed:(id)sender;
#end
TableViewController.m
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *headerView;
UIView *seperatorView;
CGRect testFrame = CGRectMake(280.0, 5.0, 30.0, 30.0);
button = [[addButtonView alloc]initWithFrame:testFrame];
NSString *sectionTitle = #"Incomplete Tasks";
NSString *section2Title = #"Completed Tasks";
UILabel *label = [[UILabel alloc]init];
label.textColor = [UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f];
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:25];
label.backgroundColor = [UIColor clearColor];
label.frame = CGRectMake(10.0, 0.0, 320.0, 40.0);
headerView = [[UIView alloc]initWithFrame:label.frame];
[button addTarget:self action:#selector(addCell:) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
CGRect sepFrame = CGRectMake(0, headerView.frame.size.height-2, 320, 1);
seperatorView = [[UIView alloc] initWithFrame:sepFrame];
seperatorView.backgroundColor = [UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f];
[headerView addSubview:seperatorView];
switch (section) {
case 0:
label.text = sectionTitle;
[headerView addSubview:label];
[headerView addSubview:button];
break;
case 1:
label.text = section2Title;
[headerView addSubview:label];
// if (completedArray == nil)
// headerView.hidden = YES;
break;
}
return headerView;
}
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
if([self isEditing]){
button.hidden = YES;
}else {
button.hidden = NO;
}
}
---EDIT----
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
if([self isEditing]){
button.hidden = YES;
[[self tableView] reloadData]; //shouldn't this make the button dissapear?
}else {
button.hidden = NO;
}
}
Whenever the table view is reloaded your code will recreate the entire header, including creating a new button. So you may have set the old button to hidden and then it gets destroyed and replaced by a new, visible, button.
When returning the header, either create it once and always return the same instance, then changing the hidden property should work. Or, check if the table isEditing each time the header is created and decide what to do as a result.
Let's go with the more efficient header reuse option:
Create a property to hold the header view(s) - an array.
In viewDidLoad create the header views (using your current code, but moved to a different method).
Add the header views to the property (ensure you initialise the array first)
Change viewForHeaderInSection to just return the header from the array (based on section)
In setEditing: iterate through the array and hide/show each button
(You could store the buttons in another array to make that easy)
Trying to place a UILabel containing the date in the lower right hand corner of a cell whether it's on an iPhone or iPad.
Here's what I currently have, what do I need to do to get the actual cell size.width, tried doing cell.bounds.size.width as well, same value whether iPhone or iPad:
float xValue = cell.frame.size.width - 100;
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(xValue, 20.0f, 100, 17.0f)];
[nameLabel setTag:1];
[nameLabel setFont:[UIFont boldSystemFontOfSize:15.0]];
nameLabel.textColor = [UIColor grayColor];
nameLabel.text = #"05-12-13";
// custom views should be added as subviews of the cell's contentView:
[cell.contentView addSubview:nameLabel];
ETA, here is the whole custom cell class, maybe someone can see what's causing the duplication of the label:
#interface VideoTableViewCell : UITableViewCell
+ (VideoTableViewCell *)cellForTableView:(UITableView *)tableView;
+ (CGFloat)heightForVideo:(id<VideoProtocol>)video;
- (void)updateCellForVideo:(id<VideoProtocol>)video;
#end
#define MARGIN 10
#implementation VideoTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.textLabel.font = [UIFont boldSystemFontOfSize:14];
self.detailTextLabel.font = [UIFont systemFontOfSize:13];
self.textLabel.numberOfLines = 2;
self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return self;
}
+ (VideoTableViewCell *)cellForTableView:(UITableView *)tableView {
NSString *identifier = #"TweetCell";
VideoTableViewCell *cell = (VideoTableViewCell *)[tableView
dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[VideoTableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:identifier];
}
return cell;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect cvf = self.contentView.frame;
self.imageView.frame = CGRectMake(0.0,
0.0,
cvf.size.height-1,
cvf.size.height-1);
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
CGRect frame = CGRectMake(cvf.size.height + MARGIN,
self.textLabel.frame.origin.y,
cvf.size.width - cvf.size.height - 2*MARGIN,
self.textLabel.frame.size.height);
self.textLabel.frame = frame;
frame = CGRectMake(cvf.size.height + MARGIN,
self.detailTextLabel.frame.origin.y,
cvf.size.width - cvf.size.height - 2*MARGIN,
self.detailTextLabel.frame.size.height);
self.detailTextLabel.frame = frame;
}
- (void)setDateLabelWithDate:(NSDate *)date {
float xValue = self.frame.size.width - 70;
// create a custom label: x y width height
UILabel *dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(xValue, 40.0f, 100, 12.0f)];
dateLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
[dateLabel setFont:[UIFont boldSystemFontOfSize:13.0]];
dateLabel.textColor = [UIColor grayColor];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yy"];
NSString *dateString = [dateFormatter stringFromDate:date];
dateLabel.text = dateString;
[self.contentView addSubview:dateLabel];
}
+ (CGFloat)heightForVideo:(id<VideoProtocol>)video {
//create a dummy cell
VideoTableViewCell *sampleCell = [[VideoTableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:nil];
[sampleCell updateCellForVideo:video];
//calculate the sizes of the text labels
CGSize textSize = [video.title sizeWithFont: [VideoTableViewCell textLabelFont]
constrainedToSize:sampleCell.textLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGFloat minHeight = 51 + 10; //image height + margin
return MAX(textSize.height + 20, minHeight);
}
+ (UIFont *)textLabelFont {
return [UIFont systemFontOfSize:13];
}
- (void)updateCellForVideo:(id<VideoProtocol>)video {
// set the text to the date with the tweet text
self.textLabel.text = video.title;
id<VideoAttrProtocol> speaker = [[video.speakers allObjects] objectAtIndex:0];
self.detailTextLabel.text = speaker.name;
[self setDateLabelWithDate:video.post_date];
NSURL *url = [NSURL URLWithString:video.thumbnail];
[self.imageView setImageWithURL:url
placeholderImage:[UIImage imageNamed:#"Logo.png"]];
}
#end
You need to set the label's autoresizingMask. Put the label in the correct place based on the cell's initial size, whatever it is. With the autoresizingMask set properly, the label will adjust as the cell's size changes.
Just before adding the label to the content view, add:
// Keep the label in the bottom-right corner
nameLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
Update based on all of the posted code:
In your custom cell, you create and add a label every time the setDataLabelWithDate: method is called.
You call this method from updateCellForVideo: and possibly from your view controller (you don't show that code).
You need to update your code so you do not add a new label to the cell every time setDataLabelWithDate: is called. Only add the label once.
Hello all,
I have to add one more view in cell of GMGridView. But i am unable to do this because i have to drag my label from view to view1.
My code is :
- (GMGridViewCell *)GMGridView:(GMGridView *)gridView1 cellForItemAtIndex:(NSInteger)index
{
// set size based on orientation
CGSize size = [self GMGridView:gridView sizeForItemsInInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
GMGridViewCell *cell = [gridView dequeueReusableCell];
if (!cell)
{
cell = [[[GMGridViewCell alloc]init]autorelease];
//one view
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
view.backgroundColor = [UIColor redColor];
view.layer.masksToBounds = NO;
view.layer.cornerRadius = 2;
cell.contentView = view;
//another view
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 80, size.width, size.height)];
view1.backgroundColor = [UIColor yellowColor];
view1.layer.masksToBounds = NO;
view1.layer.cornerRadius = 2;
cell.contentView = view1;
}
[[cell.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
// allocate label
UILabel *label = [[UILabel alloc] initWithFrame:cell.contentView.bounds];
label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
label.text = (NSString *)[self.currentData objectAtIndex:index];
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.font = [UIFont boldSystemFontOfSize:20];
[cell.contentView addSubview:label];
return cell;
}
height of cell is 200. but still it shows only one view.
Loading Two types of Cell in GMGridView
This is your Solution, it works as charm..
First Do this Exactly
-(void)prepareExhibitor
{
NSInteger spacing = 1.0;
CGRect rect=self.view.frame;
rect.origin=CGPointMake(0, 0);
self.gmGridView = [[GMGridView alloc] initWithFrame:rect];
self.gmGridView.backgroundColor = [UIColor clearColor];
self.gmGridView.centerGrid=NO;
self.gmGridView.style = GMGridViewStylePush;
self.gmGridView.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutHorizontal];
self.gmGridView.showsHorizontalScrollIndicator=FALSE;
self.gmGridView.clipsToBounds=YES;
self.gmGridView.itemSpacing = spacing;
self.gmGridView.minEdgeInsets = UIEdgeInsetsMake(0,30, 0, 0);
[self.viewNewsHeadline addSubview:self.gmGridView];
self.gmGridView.actionDelegate = self;
self.gmGridView.dataSource = self;
self.gmGridView.mainSuperView = self.superView;
}
Then Write this accordingly as per your Code
- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index
{
GMGridViewCell *cell = [gridView dequeueReusableCell];
NewsCell_iPad *view;
UIViewController *controller;
if (!cell)
{
// [self removeGrid];
cell = [[GMGridViewCell alloc] init];
if(index%2==0)
{
controller=[[UIViewController alloc] initWithNibName:#"NewsCellTypeA_iPad" bundle:nil];
}
else
{
controller=[[UIViewController alloc] initWithNibName:#"NewsCellTypeB_iPad" bundle:nil];
}
if(!view)
{
view=(NewsCell_iPad *)controller.view;
}
cell.layer.masksToBounds = NO;
cell.contentView = view;
}
NewsCell_iPad *newsView=(NewsCell_iPad *)cell.contentView;
newsView.news=[self.arrNews objectAtIndex:index];
[self hideGradientBackground:newsView.webViewDetailedNews];
[newsView downloadImage];
[newsView loadWebView];
// NSLog(#"cell=%d ,arr image index=%#",index,[self.arrNews objectAtIndex:index]);
return cell;
}
Okay, a short breif of my app before i explain the problem.
My app has two views for it's custom TableViewCell, one frontview, and one backview(which is revealed once you swipe your finger across the cell, much like the twitter-app).
Anywho, i wanted to have some buttons on the backview. I did this in the cellForRowAtIndexPath-method
The first you'll see here is how i assign labels to the cells. The secondary thing you'll see is the button. It's working fine.
UILabel *nextArtist = [UILabel alloc];
nextArtist.text = #"Rihanna";
nextArtist.tag = 4;
[cell setNextArtist:nextArtist];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(6 ,31, 110, 20);
[button setImage:[UIImage imageNamed:#"radionorge.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(touched:) forControlEvents:UIControlEventTouchUpInside];
[cell.backView addSubview:button];
But, it's in the next method the problem occours.
-(void)touched:(id)sender {
// Here i want to get the UILabels for each cell. Such as nextArtist.
if ([sender isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)sender;
UIView *contentView = button.superview;
UIView *viewWithTag4 = [contentView viewWithTag:4];
if ([viewWithTag1 isKindOfClass:[UILabel class]]) {
UILabel *titleLabel = (UILabel *)viewWithTag4;
NSLog(#"Label: ",titleLabel.text);
}
}
}
So, i realised that i cannot just go to the superview of the button and find my labels there, because their in another subview. I have scanned all my views, but still cannot find the label.
I am very new at this, and the subclassing of the TableView-cell is something i implemented from someone who posted their code.
But, my assumption is that there are noe UILabels in my view, because i am not adding them as views, only drawing them, with the drawTextInRect-function.
[nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];
I have tried to adding them as subviews, but with no luck. Could anyone help me?
// Some more code you may need to solve the puzzle(this is where the cell-views are made)
#implementation RadioTableCellView
- (void)drawRect:(CGRect)rect {
if (!self.hidden){
[(RadioTableCell *)[self superview] drawContentView:rect];
}
else
{
[super drawRect:rect];
}
}
#end
#implementation RadioTableCellBackView
- (void)drawRect:(CGRect)rect {
if (!self.hidden){
[(RadioTableCell *)[self superview] drawBackView:rect];
}
else
{
[super drawRect:rect];
}
}
#end
#interface RadioTableCell (Private)
- (CAAnimationGroup *)bounceAnimationWithHideDuration:(CGFloat)hideDuration initialXOrigin:(CGFloat)originalX;
#end
#implementation RadioTableCell
#synthesize contentView;
#synthesize backView;
#synthesize contentViewMoving;
#synthesize selected;
#synthesize shouldSupportSwiping;
#synthesize shouldBounce;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
[self setBackgroundColor:[UIColor clearColor]];
RadioTableCellView * aView = [[RadioTableCellView alloc] initWithFrame:CGRectZero];
[aView setClipsToBounds:YES];
[aView setOpaque:YES];
[aView setBackgroundColor:[UIColor clearColor]];
[self setContentView:aView];
[aView release];
RadioTableCellBackView * anotherView = [[RadioTableCellBackView alloc] initWithFrame:CGRectZero];
[anotherView setOpaque:YES];
[anotherView setClipsToBounds:YES];
[anotherView setHidden:YES];
[anotherView setBackgroundColor:[UIColor clearColor]];
[self setBackView:anotherView];
[anotherView release];
// Backview must be added first!
// DO NOT USE sendSubviewToBack:
[self addSubview:backView];
[self addSubview:contentView];
[self setContentViewMoving:NO];
[self setSelected:NO];
[self setShouldSupportSwiping:YES];
[self setShouldBounce:YES];
[self hideBackView];
}
return self;
}
Please help me, or at least point me in a direction or two!
//////////////////////////
Updated with some new code:
This is inside my RadioCustomCell, a UIView-subclass. It's here the UILabels are drawn
#import "RadioCustomCell.h"
#implementation RadioCustomCell
#synthesize nowTitle,nowArtist,nextTitle,nextArtist,ChannelImage;
// Setting the variables
- (void)setNowTitle:(UILabel *)aLabel {
if (aLabel != nowTitle){
[nowTitle release];
nowTitle = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNowArtist:(UILabel *)aLabel {
if (aLabel != nowArtist){
[nowArtist release];
nowArtist = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNextTitle:(UILabel *)aLabel {
if (aLabel != nextTitle){
[nextTitle release];
nextTitle = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNextArtist:(UILabel *)aLabel {
if (aLabel != nextArtist){
[nextArtist release];
nextArtist = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setChannelImage:(UIImage *)aImage {
if (aImage != ChannelImage){
[ChannelImage release];
ChannelImage = [aImage retain];
[self setNeedsDisplay];
}
}
- (void)drawContentView:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//UIColor * backgroundColour = [UIColor whiteColor];
UIColor *backgroundColour = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"CellBackground.png"]];
[backgroundColour set];
CGContextFillRect(context, rect);
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
[ChannelImage drawInRect:CGRectMake(boundsX+120 ,25, 75, 35)];
nowTitle.enabled = YES;
nowTitle.textAlignment = UITextAlignmentCenter;
nowTitle.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size: 14.0];
nowTitle.textColor = [UIColor blackColor];
nowTitle.backgroundColor = [UIColor clearColor];
//[nowTitle drawTextInRect:CGRectMake(boundsX+6 ,31, 110, 20)];
// Trying to add a subview instead of drawing the text
nowTitle.frame = CGRectMake(boundsX+6 ,31, 110, 20);
[self addSubview:nowTitle];
// I have also tried adding it to super, no effect.
nowArtist.enabled = YES;
nowArtist.textAlignment = UITextAlignmentCenter;
nowArtist.font = [UIFont fontWithName:#"HelveticaNeue" size: 10.0];
nowArtist.textColor = [UIColor blackColor];
nowArtist.backgroundColor = [UIColor clearColor];
[nowArtist drawTextInRect:CGRectMake(boundsX+6 ,46, 110, 15)];
nextTitle.enabled = NO;
nextTitle.textAlignment = UITextAlignmentCenter;
nextTitle.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size: 12.0];
[nextTitle drawTextInRect:CGRectMake(boundsX+200 ,31, 110, 20)];
nextArtist.enabled = NO;
nextArtist.textAlignment = UITextAlignmentCenter;
nextArtist.font = [UIFont fontWithName:#"HelveticaNeue" size: 9.0];
[nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];
}
You just forgot to init your UILabel in your very first line of code. :)
At the first look, I can be sure that if you draw the text (and the text is not the label), then there is no UILabel at all in your cell. You can ignore that way.
So, if you don't have the UILabel, how you can get the text. Because your contentView is indeed a RadioTableCellView, then it is not hard. In your class, just public a property called nextArtist. When your button is tapped, look up for the contentView (by calling some superview), cast it to RadioTableCellView then get the nextArtist out
Without writing a bunch of code, here's my best guess.
You're going to need to assign tags to aView and anotherView in your initWithStyle: method. I'm going to assume you have a couple constants: BACK_VIEW_TAG and FRONT_VIEW_TAG.
In your touched: method, walk up the view hierarchy until you find your UITableViewCell.
UIView *currentView = button.superView;
while (![currentView isKindOfClass:UITableViewCell] && currentView != nil) {
currentView = currentView.parent;
}
Get the front view and back view (or which ever you want) from the table cell's contentView using the tags.
if (currentView != nil) {
UITableViewCell *cellView = (UITableViewCell *)currentView)
UIView *cellContentView = cellView.contentView;
UIView *backView = [cellContentView viewWithTag:BACK_VIEW_TAG];
UIView *frontView = [cellContentView viewWithTag:FRONT_VIEW_TAG];
// Get other views from frontView and backView using viewWithTag:.
}
Note that you should be adding views to your UITableViewCell subclass's contentView, not to the UITableViewCell directly. See Programmatically Adding Subviews to a Cell’s Content View for details.
I created a custom UITableViewCell class with a UIButton, a UIImage, and two UILabels. The button and the image are overlayed on top of each other, and only one is displayed at a time. The expected behavior is you touch on the button, the button disappears, and it displays the image. The UITableViewCells are set to be reused. Here's my code:
Constructor:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
unheartButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
unheartButton.backgroundColor = [UIColor clearColor];
unheartButton.frame = CGRectMake(10, 13, 20, 18);
[unheartButton addTarget:self action:#selector(onButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[unheartButton setBackgroundImage:[UIImage imageNamed:#"redheart.png"] forState:UIControlStateNormal];
imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(12, 13, 16, 16);
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int ndx = 1; ndx < 13; ndx++) {
[array addObject:[UIImage imageNamed:[NSString stringWithFormat:#"icon-loading-%d (dragged).tiff", ndx]]];
}
imageView.animationImages = array;
imageView.animationDuration = 1;
[array release];
[self.contentView addSubview:imageView];
[self.contentView addSubview:unheartButton];
return self;
}
}
- (void) setModel:(MyModel *)myModel {
model = myModel;
if (model.hideImage) {
imageView.hidden = YES;
unheartButton.hidden = NO;
else {
imageView.hidden = NO;
unheartButton.hidden = YES;
}
}
Button click:
- (IBAction) onButtonClick: (id) sender {
model.hideImage = NO;
unheartButton.hidden = YES;
imageView.hidden = NO;
[imageView startAnimating];
[self setNeedsDisplay];
[self.contentView setNeedsDisplay];
[self.unheartButton setNeedsDisplay];
[self.imageView setNeedsDisplay];
}
I'm calling setNeedsDisplay on everything, but nothing seems to happen. If I scroll off the screen and back up, the button is hidden and now the loading icon is shown, but this only happens after a scroll. I'm not sure what I need to do to get the cell to repaint.
The UITableView does some fancy caching to support scrolling and the like; I've had similar issues with refreshing a specific cell when I use custom views.
You can use reloadRowsAtIndexPaths:withRowAnimation: to make the table reload just that row. See this post for more information: Why won't my UITableViewCell deselect and update its text?