iPhone UITableView - Delete Button - iphone

I am using the 'swipe to delete' functionality of the UITableView.
The problem is I am using a customised UITableViewCell which is created on a per item basis in
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I need to alter the position of the delete button (simply to move it around 10px to the left), how would I go about doing this?
Here is my existing code for creating the cell:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cellForRowAtIndexPath");
#if USE_CUSTOM_DRAWING
const NSInteger TOP_LABEL_TAG = 1001;
const NSInteger BOTTOM_LABEL_TAG = 1002;
UILabel *topLabel;
UILabel *bottomLabel;
#endif
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//
// Create the cell.
//
cell =
[[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier]
autorelease];
#if USE_CUSTOM_DRAWING
const CGFloat LABEL_HEIGHT = 20;
UIImage *image = [UIImage imageNamed:#"trans_clock.png"];
//
// Create the label for the top row of text
//
topLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT),
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:topLabel];
//
// Configure the properties for the text that are the same on every row
//
topLabel.tag = TOP_LABEL_TAG;
topLabel.backgroundColor = [UIColor clearColor];
topLabel.textColor = fontColor;
topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//
// Create the label for the top row of text
//
bottomLabel =
[[[UILabel alloc]
initWithFrame:
CGRectMake(
image.size.width + 2.0 * cell.indentationWidth,
0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT,
aTableView.bounds.size.width -
image.size.width - 4.0 * cell.indentationWidth
,
LABEL_HEIGHT)]
autorelease];
[cell.contentView addSubview:bottomLabel];
//
// Configure the properties for the text that are the same on every row
//
bottomLabel.tag = BOTTOM_LABEL_TAG;
bottomLabel.backgroundColor = [UIColor clearColor];
bottomLabel.textColor = fontColor;
bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];
//
// Create a background image view.
//
cell.backgroundView =
[[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView =
[[[UIImageView alloc] init] autorelease];
#endif
}
#if USE_CUSTOM_DRAWING
else
{
topLabel = (UILabel *)[cell viewWithTag:TOP_LABEL_TAG];
bottomLabel = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
}
topLabel.text = #"Example Text";
topLabel.textColor = fontColor;
bottomLabel.text = #"More Example Text";
bottomLabel.textColor = fontColor;
//
// Set the background and selected background images for the text.
// Since we will round the corners at the top and bottom of sections, we
// need to conditionally choose the images based on the row index and the
// number of rows in the section.
//
UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [aTableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 && row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"topAndBottomRow.png"];
selectionBackground = [UIImage imageNamed:#"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
rowBackground = [UIImage imageNamed:#"topRow.png"];
selectionBackground = [UIImage imageNamed:#"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:#"bottomRow.png"];
selectionBackground = [UIImage imageNamed:#"bottomRowSelected.png"];
}
else
{
rowBackground = [UIImage imageNamed:#"middleRow.png"];
selectionBackground = [UIImage imageNamed:#"middleRowSelected.png"];
}
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
cell.imageView.image = [UIImage imageNamed:#"Example_Image.png"];
#else
cell.text = #"Example";
#endif
return cell;
}

For me the best way to solve this was overriding -(void)layoutSubviews in MyCell:UITableViewCell
Here you can see not only the Delete button custom position, but also repositioning the Edit and Reorder controls for Edit mode
- (void)layoutSubviews
{
[super layoutSubviews];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0f];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 200;
subview.frame = newFrame;
}
else if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellEditControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 100;
subview.frame = newFrame;
}
else if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellReorderControl"]) {
CGRect newFrame = subview.frame;
newFrame.origin.x = 200;
subview.frame = newFrame;
}
}
[UIView commitAnimations];
}

Iwat's code doesn't work for me. But this works.
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
subview.hidden = YES;
subview.alpha = 0.0;
}
}
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
[super didTransitionToState:state];
if (state == UITableViewCellStateShowingDeleteConfirmationMask || state == UITableViewCellStateDefaultMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect f = deleteButtonView.frame;
f.origin.x -= 20;
deleteButtonView.frame = f;
subview.hidden = NO;
[UIView beginAnimations:#"anim" context:nil];
subview.alpha = 1.0;
[UIView commitAnimations];
}
}
}
}

I haven't been able to change the actual look of the delete button, but you can change the text. Perhaps you can use this to get the effect you are looking for?
Check out the following member of the UITableViewDelegate protocol:
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
Additionally, you can detect when the delete button is being displayed by subclassing UITableViewCell and overriding the the following:
- (void)willTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state
For either of these, the state mask will be UITableViewCellStateShowingDeleteConfirmationMask when the delete button is being displayed.
Hopefully these clues will point you in the right direction.

I use a solution that on first sight looks kind of hacky but does the trick and is not relying on undocumented apis:
/**
* Transition to state
*/
-(void)willTransitionToState:(UITableViewCellStateMask)state {
if(state & UITableViewCellStateShowingDeleteConfirmationMask)
_deleting = YES;
else if(!(state & UITableViewCellStateShowingDeleteConfirmationMask))
_deleting = NO;
[super willTransitionToState:state];
}
/**
* Reset cell transformations
*/
-(void)resetCellTransform {
self.transform = CGAffineTransformIdentity;
_background.transform = CGAffineTransformIdentity;
_content.transform = CGAffineTransformIdentity;
}
/**
* Move cell around if we are currently in delete mode
*/
-(void)updateWithCurrentState {
if(_deleting) {
float x = -20;
float y = 0;
self.transform = CGAffineTransformMakeTranslation(x, y);
_background.transform = CGAffineTransformMakeTranslation(-x, -y);
_content.transform = CGAffineTransformMakeTranslation(-x, -y);
}
}
-(void)setFrame:(CGRect)frame {
[self resetCellTransform];
[super setFrame:frame];
[self updateWithCurrentState];
}
-(void)layoutSubviews {
[self resetCellTransform];
[super layoutSubviews];
[self updateWithCurrentState];
}
Basically this shifts the cell position and readjusts the visible portions.
WillTransitionToState just sets an instance variable indicating whether the cell is in delete mode. Overriding setFrame was necessary to support rotating the phone to landscape and vice-versa.
Where _background is the background view of my cell and _content is a view added to the contentView of the cell, holding all labels etc.

I don't know of any way to "move the delete button 10px to the left". However, you can animate the custom contents of your table cell around the static position of the unmovable delete button by listening for the willTransitionToState: message from a UITableViewCell sub-class see here.
To quote the docs:
Subclasses of UITableViewCell can
implement this method to animate
additional changes to a cell when it
is changing state. UITableViewCell
calls this method whenever a cell
transitions between states, such as
from a normal state (the default) to
editing mode. The custom cell can set
up and position any new views that
appear with the new state. The cell
then receives a layoutSubviews message
(UIView) in which it can position
these new views in their final
locations for the new state.
Subclasses must always call super when
overriding this method.
What you are looking for is the UITableViewCellStateShowingDeleteConfirmationMask value. This is one of those times where creating UITableViewCell subclass might be better, so from the controller you are just creating an instance of your custom cell. Then the cell can just adjust itself like animateLeft and animateRight and handle the inner workings of adjusting its own subviews.

I don't know the final solution, but as far as I tried the following code might be useful.
// subclass UITableViewCell
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
{
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
subview.hidden = YES;
subview.alpha = 0;
}
}
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableCellStateShowingDeleteConfirmationMask)
{
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
subview.frame = CGRectMake(subview.frame.origin.x - 10, subview.frame.origin.y, subview.frame.size.width, subview.frame.size.height);
subview.hidden = NO;
[UIView beginAnimations:#"anim" context:nil];
subview.alpha = 1;
[UIView commitAnimations];
}
}
}
}

Related

Scrolling horizontal and vertical both direction

I have requirement to scroll the images horizontally and vertically.
I have sections which will segregated vertically and in each section itself it will be so many images which will be scrolled horizontally.
I made vertical scrolling using UICollectionView with Ray wenderlich tutorial but how do I get horizontal scrolling in each section?
Should I use any other object like UITableView or UIScrollview for this purpose?
Any tutorial available how to achieve this?
Is it compulsory to implement Layout subclass or UICollectionviewFlowlayout when using collection view?
EDIT
Till now I have implemented this code which scrolls vertically and has 5 sections each but not able to scroll the individual sections
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
NSArray *arrayReturn = [self returnArray:section];
return arrayReturn.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 5;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ImageCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"imagecell" forIndexPath:indexPath];
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSArray *arrSection = [NSArray arrayWithArray:[self returnArray:indexPath.section]];
NSString *fileName = [arrSection objectAtIndex:indexPath.row];
UIImage *image = [UIImage imageNamed:fileName];
dispatch_async(dispatch_get_main_queue(), ^{
// cell.imgVw.image = ;
if([CollectionView.indexPathsForVisibleItems containsObject:indexPath]){
ImageCell *currentCell = (ImageCell *) [cv cellForItemAtIndexPath:indexPath];
currentCell.imgVw.image = image;
}
});
}];
[self.thumbnailQueue addOperation:operation];
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
HeaderView *Header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"PhotoHeaderView" forIndexPath:indexPath];
Header.lblHeaderTitle.text = #"Header title";
Header.backgroundColor = [UIColor yellowColor];
return Header;
}
Here is a similar tutorial:
http://www.raywenderlich.com/4723/how-to-make-an-interface-with-horizontal-tables-like-the-pulse-news-app-part-2
Basically you need to do following:
Take a tableView or CollectionView
In each cell you need to add a scrollview with horizontal scrolling enabled.
Add items to scroll view of each cell while creating cells and give the scroll view appropriate content size.
It will give you a desired result.
Try this
**viewController.h**
IBOutlet UIScrollView *scrollViewMain;
**viewController.m**
- (void)viewDidLoad
{
[super viewDidLoad];
[self createDisplay];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) createDisplay
{
for(UIView *subView in scrollViewMain.subviews)
{
if(![subView isKindOfClass:[UIImageView class]])
{
[subView removeFromSuperview];
}
}
int yPos =5;
for (int i=0; i< 10; i++)
{
int xPosition=5;
UIScrollView *scrollView =[[UIScrollView alloc]initWithFrame:CGRectMake(xPosition, yPos, scrollViewMain.frame.size.width, 100)];
scrollView.backgroundColor =[UIColor clearColor];
scrollView.autoresizingMask =UIViewAutoresizingFlexibleWidth;
xPosition +=5;
for (int j=0; j<10; j++)
{
UILabel *lblTitle = [[UILabel alloc] initWithFrame:CGRectMake(xPosition, 0, 100, 100)];
lblTitle.textColor = [UIColor whiteColor];
lblTitle.backgroundColor =[UIColor greenColor];
lblTitle.text = #"test";
lblTitle.numberOfLines =0;
lblTitle.font = [UIFont boldSystemFontOfSize:15];
[scrollView addSubview:lblTitle];
xPosition +=100;
xPosition +=10;
}
[scrollView setContentSize:CGSizeMake(xPosition, 100)];
[scrollViewMain addSubview:scrollView];
yPos +=120;
}
[scrollViewMain flashScrollIndicators];
[scrollViewMain setContentSize:CGSizeMake(0, yPos)];
}

How to connect scrollview to page control in TableView Cell

I have a custom cell designed with a scrollview and a pageview control, which I am displaying as follows
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = #"ScrollViewCell";
cell = (ScrollViewCell*)[newsTable dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray * customcellArray = [[NSBundle mainBundle]loadNibNamed:#"ScrollViewCell" owner:self options:nil];
for(id customcellObject in customcellArray){
if([customcellObject isKindOfClass: [UITableViewCell class]]){
cell = (ScrollViewCell *)customcellObject;
break;
}
}
}
// Customize your UIScrollView here..
[cell.scrollView setDelegate:self];
[cell.scrollView setPagingEnabled:YES];
scrollView = cell.scrollView;
pageControl = cell.pageControl;
cell.backgroundColor = [UIColor grayColor];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor], nil];
cell.scrollView.contentSize = CGSizeMake(cell.scrollView.frame.size.width * colors.count,cell.scrollView.frame.size.height);
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = cell.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = cell.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[cell.scrollView addSubview:subview];
}
// Configure the cell...
UIView* bgview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
bgview.opaque = YES;
bgview.backgroundColor = [UIColor grayColor];
[cell setBackgroundView:bgview];
return cell;
}
The scrollview appears and scrolls just fine in cell , but problem is page control doesnt update with the scroll, basically I want to update the page control on scroll of scrollview but since page control and scrollview both are from cell I am not getting how to achieve this, I tried implementing UIScrollViewDelegate protocol with cell and then the parent view of table view but couldnt get it working, pleas guide.
Thanks
Vishal
Don't place your UIPageControll over UIScrollview in your custom cell, if it is then it will get scroll along UIScrollView itself.So create your Custom cell like this and make outlet for each UIScrollview & UIPageControll,
One change in your cellForRowAtIndexPath
// Customize your UIScrollView here..
[cell.scrollView setDelegate:self];
[cell.scrollView setPagingEnabled:YES];
[cell.scrollView setTag:indexPath.row]; // set indexpath.row as tag for cell.scrollview
NSArray * colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor],nil];
cell.pageControll.numberOfPages = [colors count];
And in,
- (void)scrollViewDidScroll:(UIScrollView *)sender {
CGFloat xOffset = sender.contentOffset.x;
CGFloat frameWidth = sender.frame.size.width;
int page = floor((xOffset - frameWidth / 2) / frameWidth) + 1;
GroupButtonCell * cell = (GroupButtonCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0]]; // get appropriate cell based on scrollview tag (sender.tag).
cell.pageControll.currentPage = page; // assigning to pagecontroll
}
Hope this will help..

ScrollView with paging in TableView Cell

I have to create a tableview with one of the cell having a scrollview with paging enabled and paging control in it. I have already tried following.
I have created a TableView Cell in IB which has two things in it
1.ScrollView
2.Page control and some labels placed at runtime on each page of scrollview, I have tested this scrollview and paging control in normal view and it works as expected.
I have following code in the ScrollViewCell.h
#import <UIKit/UIKit.h>
#interface ScrollViewCell : UITableViewCell<UIScrollViewDelegate>
{
UIPageControl* pageControl;
UIScrollView* scrollView;
BOOL pageControlBeingUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl* pageControl;
- (IBAction)changePage;
#end
And following code in ScrollViewCell.m
#import "ScrollViewCell.h"
#implementation ScrollViewCell
#synthesize scrollView;
#synthesize pageControl;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [UIColor grayColor];
[self.scrollView addSubview:subview];
// add buttons
CGRect Frame= CGRectMake(frame.origin.x,frame.origin.y,200,50);
//set your x and y position whatever u want.
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
Button.frame = Frame;
UIImage *Img = [UIImage imageNamed:#"second.png"];
[Button setBackgroundImage:Img forState:UIControlStateNormal];
[scrollView addSubview: Button];
// add text
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(frame.origin.x,frame.origin.y+60,200,50)];
label.textAlignment = UITextAlignmentCenter;
label.text = #"Here you write your text";
label.textColor = [UIColor blackColor];
[scrollView addSubview:label ];
[subview release];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * colors.count, self.scrollView.frame.size.height);
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page isvisible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (IBAction)changePage {
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
#end
I am loading this cell in the table view as follows
static NSString *CellIdentifier = #"ScrollViewCell";
ScrollViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ScrollViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
When I am running this app it shows an empty table with desired height but nothing in it.
Is my approach correct ? if yes whats missing ?
Thanks
Regards
Vishal
You are trying to add customize your UIScrollView in UITableViewCell class itself, i am not sure whether it will work.
instead try like this in your UITableView class cellForRowAtIndexPath,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"GroupButtonCell";
CustomCell * cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray * customcellArray = [[NSBundle mainBundle]loadNibNamed:#"CustomCell" owner:self options:nil];
for(id customcellObject in customcellArray){
if([customcellObject isKindOfClass: [UITableViewCell class]]){
cell = (CustomCell *)customcellObject;
break;
}
}
}
// Customize your UIScrollView here..
[cell.scrollView setDelegate:self];
[cell.scrollView setPagingEnabled:YES];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor], nil];
cell.scrollView.contentSize = CGSizeMake(cell.scrollView.frame.size.width * colors.count,cell.scrollView.frame.size.height);
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = cell.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = cell.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[cell.scrollView addSubview:subview];
}
// Configure the cell...
return cell;
}
try this in ScrollViewCell.m
Inside init method.
[self.contentView addSubview:scrollView];
You should add scrollview on cell. Check M not sure. I dint got time to try in project.

UIScrollView in custom table cell at cellForRowAtIndex path not working

I'm trying to implement a UIScrollView in each cell of `UITableView'. I wrote my code based on Apple's custom Scrollview project: https://developer.apple.com/library/ios/#samplecode/Scrolling/Listings/ReadMe_txt.html
Each table cell's UIScrollView scrolls through a set of labels, which are initialized in the cellForRowAtIndexPath method. Each label's text is set after initialization to equal a string from an array.
Everything works correctly until I scroll down to the 4th table cell. The UIScrollView in this cell has the same exact labels as the first cell. The same first 3 set of labels or the first 3 scrollViews keep repeating after the first 3 cells. The strange part is, when I log the label.text after it is set, the output shows the correct label.text of what should be displaying in the respective cell.
- (void)layoutScrollLabels: (float)arrayCount
{
UIView *view = nil;
NSArray *subviews = [cell.popularLinkScrollView subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UILabel class]] && view.tag >= 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
[cell.popularLinkScrollView setContentSize:CGSizeMake((arrayCount * kScrollObjWidth), [cell.popularLinkScrollView bounds].size.height)];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Custom Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *dictionary = [parseDataArray objectAtIndex:indexPath.row];
NSArray *popularLinkTitleArray = [dictionary objectForKey:#"popularLinkTitleArray"];
cell.popularLinkScrollView.clipsToBounds = YES;
kScrollObjHeight = cell.popularLinkScrollView.frame.size.height;
kScrollObjWidth = cell.popularLinkScrollView.frame.size.width;
NSUInteger i;
for (i = 0; i < popularLinkTitleArray.count; i++)
{
NSString *string = [NSString stringWithFormat:#"%#", [popularLinkTitleArray objectAtIndex: i]];
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:#"%#", string];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 5;
NSLog(#"%#", label.text);
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = label.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
label.frame = rect;
label.tag = i; // tag our images for later use when we place them in serial fashion
[cell.popularLinkScrollView addSubview:label];
}
[self layoutScrollLabels:popularLinkTitleArray.count];
}
return cell;
}
You should not add label as a subview to popularLinkScrollView in cellForRowAtIndexPath. If the count of labels is required to be dynamic, try this code before your for loop in cellForRowAtIndexPath.
for (UIView* subView in cell.popularLinkScrollView.subviews)
[subView removeFromSuperview];

UILabel in viewForFooterInSection text problem

I want to display two lots of text in two different footers in my table.
The text for section 3 uses titleForFooterInSection :
- (NSString *)tableView:(UITableView *)tv titleForFooterInSection:(NSInteger)section
{
if (section == 3)
return #"SOME TEXT FOR SECTION 3";
else
return #"";
}
and works great and is styled correctly.
I also want to add some more complicatedly formatted text (just left aligned really), so I create a label and add it to viewForFooterInSection, which works but is not padded (doesn't start at x = 20 & y = 20, starts hard up against the main windows edge) and is not styled like the other text.
- (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
{
if (section == 1)
{
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 100, 50)] autorelease];
label.text = #"SOME COMPLICATED TEXT FOR SECTION 1\r\n"
"\r\n"
"MORE TEXT HERE\r\n"
"AND HERE.\r\n"
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont systemFontOfSize:14];
label.shadowColor = [UIColor colorWithWhite:0.8 alpha:0.8];
label.textColor = [UIColor blueColor];
label.lineBreakMode = UILineBreakModeWordWrap;
label.textAlignment = UITextAlignmentLeft;
label.numberOfLines = 0;
[label sizeToFit];
return label;
}
else
return nil;
}
-(CGFloat)tableView:(UITableView *)tv heightForFooterInSection:(NSInteger)section
{
if (section == 1)
return 180.0f;
else if (section == 3)
return 50.0f;
else
return 0.0f;
}
To get the padding add the label into another view before returning that as the footer view;
- (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
{
...
CGRect footerFrame = [tv rectForFooterInSection:1];
CGRect labelFrame = CGRectMake(20, 20, footerFrame.size.width - 40, footerFrame.size.height - 40);
UIView *footer = [[UIView alloc] initWithFrame:footerFrame];
UILabel *footerLabel = [[UILabel alloc] initWithFrame:labelFrame];
[footer addSubview:footerLabel];
[footerLabel release];
...
return footer;
}
NB: You might want to scope *footer better to avoid a memory leak or use autorelease.
I'm not sure what the system defaults are for the label it creates to hold the text you supply as the title for footer. I guess you'll need to experiment when creating the footer label as Google hasn't thrown anything useful up.
EDIT: Rather than put all the code in the viewForFooterInSection method I use a custom UIView;
#interface CustomHeaderView : UIView {
NSString *headerTitle;
}
#property (nonatomic, retain) NSString *headerTitle;
#end
#implementation CustomHeaderView
#synthesize headerTitle;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// create frame with padding
CGRect labelFrame = CGRectMake(8, 8, frame.size.width - 16, frame.size.height - 16);
UILabel *headerText = [[UILabel alloc] initWithFrame:labelFrame];
[headerText setNumberOfLines:0];
[headerText setFont:[UIFont boldSystemFontOfSize:14.0]];
[self addSubview:headerText];
[headerText release];
}
return self;
}
- (void)setHeaderTitle:(NSString *)title {
[title retain];
[headerTitle release];
UILabel *label = [[self subviews] objectAtIndex:0];
[label setText:title];
[label sizeToFit];
CGRect viewFrame = [self frame];
CGRect labelFrame = [label frame];
viewFrame.size.height = labelFrame.size.height + 16;
[self setFrame:viewFrame];
[self setNeedsLayout];
headerTitle = title;
}
- (void)dealloc {
[headerTitle release];
[super dealloc];
}
#end
This allows me to set my title text and have the header resize for the content. I lazy load this in my view controller;
#interface MyViewController
{
UIView *headerView;
}
- (UIView *) headerView;
#end
#implementation MyViewController
- (UIView *) headerView {
if(headerView)
return headerView;
float w = [[self view] bounds].size.width;
// height irrelevant as long as non zero custom view will resize
CGRect headerFrame = CGRectMake(0, 0, w, 32);
headerView = [[CustomHeaderView alloc] initWithFrame:headerFrame];
return headerView;
}
- (UIView *) tableView:(UITableView *)tv viewForHeaderInSection:(NSInteger)sec {
return [self headerView];
}
- (void) viewWillAppear:(BOOL)animated {
[(CustomHeaderView *)[self headerView] setHeaderTitle:#"My Custom Header"]];
}
#end
Make sure u return proper height in - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; delegate method.