Messy layout usint TTStyledTextLabel in TTTableViewCell - iphone

This is my first time using Three20 and I am trying to add a TTStyledTextLabel to my TTTableViewCell using the following code:
#interface ConvoreCell : TTTableViewCell{
TTStyledTextLabel * tt_title;
UITextView * title;
UILabel * detailed;
}
#property (nonatomic, retain) IBOutlet UITextView * title;
#property (nonatomic, retain) IBOutlet UILabel * detailed;
#property (nonatomic, retain) TTStyledTextLabel * tt_title;
#end
- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
if (self == [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
// Initialization code
tt_title = [[TTStyledTextLabel alloc] init];
tt_title.font = [UIFont systemFontOfSize:15];
[self.contentView addSubview:tt_title];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect frame = tt_title.frame;
frame.size.width = 640;
frame.size.height = tt_title.text.height;
frame.origin.x = 45;
frame.origin.y = 5;
tt_title.frame = frame;
}
and in my TTTableView I have:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat titleHeight = [TTStyledText textFromXHTML:[[self.posts objectAtIndex:indexPath.row] message] lineBreaks:YES URLs:YES].height;
//NSLog(#"HEIGHT IS %f", titleHeight);
return titleHeight + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ConvoreCell";
ConvoreCell *cell = (ConvoreCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ConvoreCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
TTImageView * avatar = [[TTImageView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+5, cell.frame.origin.y+5, 40, 40)];
avatar.urlPath = [[[self.posts objectAtIndex:indexPath.row] creator] img];
avatar.userInteractionEnabled = YES;
avatar.tag = indexPath.row;
[cell addSubview:avatar];
cell.tt_title.text = [TTStyledText textFromXHTML:[[self.posts objectAtIndex:indexPath.row] message] lineBreaks:YES URLs:YES];
}
However, the layout is messy as hell. Why is this?

I cannot find anything wrong with your code.
Looking at the image, what strikes me is that the last row which is correcly displayed contains a link.
What I suspect is that it could be some bug in TTStyledText, which in my experience is not really suitable for displaying full HTML.
Could you try and confirm (or dismiss) this hypothesis? Is always so that a url in a row will make it "go crazy"?
In any case, it will help to set a breakpoint on (or an NSLog after) the line
cell.tt_title.text = [TTStyledText textFromXHTML:[[self.posts objectAtIndex:indexPath.row] message] lineBreaks:YES URLs:YES];
and check what is going in cell.tt_title.text.

Related

UITableview Crash when scroll up or down and how to set horizontal scroll view to every cell

I want to display table view in which every cell contain nested UIview but i am facing some problems.
1) My app crash when i try to scroll table view.
Solved by add root view instead of subview into app delegate
Now problem number 2
2) I want to add horizontal scroll view inside table cell.so i can display 3 subview in single cell and i can scroll horizontally with in cell..how can i do that.
I want to do this..
To achive this i have code this..
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIView *wagon = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 430, 187)];
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"wagon.png"]];
wagon.backgroundColor = background;
UIScrollView *scrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 830, 187)];
scrollview.showsVerticalScrollIndicator=YES;
scrollview.scrollEnabled=YES;
scrollview.userInteractionEnabled=YES;
UIView *videoview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 220 , 100)];
UIImageView *video = [[UIImageView alloc]initWithFrame:CGRectMake(wagon.frame.origin.x+18, wagon.frame.origin.y+35, 220, 100)];
UIImage *bgImage = [UIImage imageNamed:#"video.png"];
video.image = bgImage;
videoview.contentMode = UIViewContentModeLeft;
[videoview addSubview:video];
UIView *textview = [[UIView alloc]initWithFrame:CGRectMake(wagon.frame.origin.x+238,wagon.frame.origin.y+28, 150 , 187)];
textview.contentMode = UIViewContentModeRight;
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(28,10, 150 , 87)];
label.text=#"This is testing text for IOS app to check line are aligned or not and to check video image and nested views for UIviews";
label.backgroundColor = [UIColor clearColor];
label.textColor=[UIColor redColor];
label.numberOfLines = 4;
[textview addSubview:label];
[wagon addSubview:textview];
[wagon addSubview:videoview];
[scrollview addSubview:wagon];
[self addSubview:scrollview];
}
return self;
}
and call this view from table cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"StateCell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Wagon1 *wg=[[Wagon1 alloc]init];
[cell addSubview:wg];
return cell;
}
by adding wg i get one train boggi, wagon view.. i want 2 wagon view and engine at last or first.
** Table crashing problem is solve**
1) to solve crashing problem i search on stackoverflow and i found solution like adding to delegates or change to retain or strong bla bla.. but non of these work for me.
Here is my code. and one more thing i am not use XIB , nib or storyboard..
#interface MainScreenViewController : UIViewController
{
UITableView* table;
NSString * name;
}
#property (strong, retain) UITableView *table;
#property (strong, retain) NSString *name;;
#end
.m file
#interface MainScreenViewController ()
#end
#implementation MainScreenViewController
#synthesize table;
#synthesize name;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:Nil bundle:Nil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
name=[[NSString alloc]init];
name=#"testing of row";
CGRect frame = self.view.frame;
table= [[UITableView alloc] initWithFrame:frame];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[table setDelegate:self];// app crash here
table.dataSource = self;// here also
[table reloadData];
[self.view addSubview:table];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 8;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"test";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath;
{
return 190;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = name;
return cell;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I tried your code and it is working perfectly for me , I guess problem should be with view controller initialisation , try this Applications are expected to have a root view controller at the end of application launch and let me know.
As you have mentioned
i have added both but still it crash..i got this 2013-04-23 12:37:28.361 AMM[2231:c07] Application windows are expected to have a root view controller at the end of application launch 2013-04-23 12:37:32.533 AMM[2231:c07] * -[MainScreenViewController respondsToSelector:]: message sent to deallocated instance 0x71edb70
In the application delegate file have you added the mainview controller to window's rootviewcontroller? Also could you try with some hardcoded text instead of assigning name to cell text.
Here,
Check this is happening in App Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[MainScreenViewController alloc] initWithNibName:#"MainScreenViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
and in MainScreenViewController.m
#interface MainScreenViewController () <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong)UITableView * table;
#property (nonatomic, strong)NSString * name;
#end
#implementation MainScreenViewController
#synthesize table,name;
- (void)viewDidLoad
{
[super viewDidLoad];
name = [[NSString alloc]init];
name = #"testing of row";
CGRect frame = self.view.frame;
table = [[UITableView alloc] initWithFrame:frame];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[table setDelegate:self];
[table setDataSource:self];
[self.view addSubview:table];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 8;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Test";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath;
{
return 190;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// cell.textLabel.text = name;
// Add UIScrollView for Horizontal scrolling.
NSArray * colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor],[UIColor orangeColor], [UIColor blackColor],[UIColor purpleColor], nil];
UIScrollView * scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0,0.0,320.0,190.0)];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * colors.count,scrollView.frame.size.height);
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[scrollView addSubview:subview];
}
[cell.contentView addSubview:scrollView];
return cell;
}

transform tableview

I want to images display for cell. but this code display, only white tableview.Why? Please tell me. (I use not storyboard.)
TableCell.h
#import <UIKit/UIKit.h>
#interface TableCell : UITableViewCell <UITableViewDelegate,UITableViewDataSource>
#property (nonatomic,retain) UITableView *tableCellView;
#property (nonatomic,retain) NSArray *cellArray;
-(NSString *)reuseIdentifier;
#end
TableCell.m
#import "TableCell.h"
#implementation TableCell
#synthesize tableCellView;
#synthesize cellArray;
-(NSString *)reuseIdentifier
{
return #"cell";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [cellArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableCellView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for (UIImageView *view in cell.subviews)
{
[view removeFromSuperview];
}
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 200, 200)];
imageView.image = [UIImage imageNamed:[cellArray objectAtIndex:indexPath.row]];
imageView.contentMode = UIViewContentModeCenter; // 画像サイズを合わせて貼る
CGAffineTransform rotateImage = CGAffineTransformMakeRotation(M_PI_2);
imageView.transform = rotateImage;
[cell addSubview:imageView];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 220;
}
#end
TableViewController.h
#import <UIKit/UIKit.h>
#class TableCell;
#interface TableViewController : UIViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, retain) TableCell *tableViewCell;
#property (nonatomic, retain) NSArray *titlesArray;
#property (nonatomic, retain) NSArray *peopleArray;
#property (nonatomic, retain) NSArray *thingsArray;
#property (nonatomic, retain) NSArray *fruitsArray;
#property (nonatomic, retain) NSArray *arrays;
#end
TableViewController.m
#import "TableViewController.h"
#import "TableCell.h"
#interface TableViewController ()
#end
#implementation TableViewController
#synthesize tableView;
#synthesize tableViewCell;
#synthesize titlesArray;
#synthesize peopleArray;
#synthesize thingsArray;
#synthesize fruitsArray;
#synthesize arrays;
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStylePlain];
[self.view addSubview:tableView];
titlesArray = [[NSArray alloc] initWithObjects:#"People", #"Things", #"Fruits", nil];
peopleArray = [[NSArray alloc] initWithObjects:#"Gardener.png", #"Plumber.png", #"BusinessWoman.png", #"BusinessMan.png", #"Chef.png", #"Doctor.png", nil];
thingsArray = [[NSArray alloc] initWithObjects:#"StopWatch.png", #"TrashCan.png", #"Key.png", #"Telephone.png", #"ChalkBoard.png", #"Bucket.png", nil];
fruitsArray = [[NSArray alloc] initWithObjects:#"Pineapple.png", #"Orange.png", #"Apple.png", nil];
arrays = [[NSArray alloc] initWithObjects:peopleArray, thingsArray, fruitsArray, nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrays count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [titlesArray objectAtIndex:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 220;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableCell *cell = (TableCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableViewCell" owner:self options:nil];
CGAffineTransform rotateTable = CGAffineTransformMakeRotation(-M_PI_2);
tableViewCell.tableCellView.transform = rotateTable;
tableViewCell.tableCellView.frame = CGRectMake(0, 0, tableViewCell.tableCellView.frame.size.width, tableViewCell.tableCellView.frame.size.height);
tableViewCell.cellArray = [arrays objectAtIndex:indexPath.section];
tableViewCell.tableCellView.allowsSelection = YES;
cell = tableViewCell;
}
return cell;
}
#end
AppDelegate.m
TableViewController *tvc = [[TableViewController alloc] init];
self.window.rootViewController = tvc;
UITableViewCell by default already has support for images. You do not need to to add a new UIImageView as a subview ...
So instead of this:
for (UIImageView *view in cell.subviews)
{
[view removeFromSuperview];
}
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 200, 200)];
imageView.image = [UIImage imageNamed:[cellArray objectAtIndex:indexPath.row]];
imageView.contentMode = UIViewContentModeCenter; // 画像サイズを合わせて貼る
CGAffineTransform rotateImage = CGAffineTransformMakeRotation(M_PI_2);
imageView.transform = rotateImage;
[cell addSubview:imageView];
Write this:
cell.imageView.image = [UIImage imageNamed:[cellArray objectAtIndex:indexPath.row]];
Oh, I now notice that LOTS OF OTHER STUFF is wrong with your code! Sorry to say that. Other stuff you need to change:
Copy this method from your TableCell to your TableViewController: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and remove the existing one
DELETE the TableCell class
I see you're also doing rotation... but leave that out for now. First try to make it work and THEN worry about rotation of the image.
Can I maybe advise you to read a book on iOS development? It seems as if you don't know what you're doing at all :(
But I do like to help you out. Can you maybe put all your code on http://www.github.com and invite me as a collaborator? My username is tomvanzummeren. I can make this app work for you.
your numberOfSectionsInTableView method might return 0. check the value of [arrays count]. And one more thing is you are not created UITableViewCell in proper way. That might be the problem too. Check this link for creating Custom UITableViewCell
Each UITableViewCell has an image support if it's style is default.
cell.imageView.image = yourImageView.image;
You don't need to do anything else.
You can change Image settings with changing yourImageView settings if you want.

My custom cell gets messed up after being clicked?

Before: http://tinypic.com/view.php?pic=2j6a4h4&s=6
After: http://tinypic.com/view.php?pic=demxi&s=6
I have a problem with my cell's layout in the listView after being clicked. As you can see in the before and after pictures, the 3 labels in my cells (name, book, chapter) gets all messed up? What have I missed in my code? /Regards
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BookmarkCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Bookmark *item = [self.items objectAtIndex:indexPath.row];
NSArray *chunks = [item.name componentsSeparatedByString: #","];
NSString *name;
NSString *book;
NSString *chapter;
if ([chunks count] > 0)
{
name = [chunks objectAtIndex:0];
if ([chunks count] > 1)
{
book = [chunks objectAtIndex:1];
if ([chunks count] > 2)
{
chapter = [chunks objectAtIndex:2];
}
}
}
UIView * pNewContentView= [[UIView alloc] initWithFrame:cell.contentView.bounds];
CGRect labelFrame= pNewContentView.bounds;
labelFrame.size.height= labelFrame.size.height * 0.5;
UILabel* pLabel1=[[UILabel alloc] initWithFrame:labelFrame];
[pNewContentView addSubview:pLabel1];
labelFrame.origin.y= labelFrame.size.height;
UILabel* pLabel2=[[UILabel alloc] initWithFrame:labelFrame];
[pNewContentView addSubview:pLabel2];
labelFrame.origin.y= labelFrame.origin.y + labelFrame.size.height;
UILabel* pLabel3=[[UILabel alloc] initWithFrame:labelFrame];
[pNewContentView addSubview:pLabel3];
[cell.contentView addSubview:pNewContentView];
[pLabel1 setText:(name)];
[pLabel2 setText:(book)];
[pLabel3 setText:(chapter)];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 70; // height of tableView Cell
}
Just expanding on what #onnoweb said and moving it to answer section as he's right:
What is happening is for every cell refresh, you are adding additional 3 labels to each cell causing a real bad memory hog. The paint issue is caused by new labels obscuring the old cause all labels have white BG by default.
You want to move the label creation code to where you initialize the newly created cell, but there is an issue with that where there is no elegant way to access added labels in already existing cells. My suggestion is for customized cells, such as this one, always create a customized subclass of UITableViewCell. (I personally think it's the most elegant approach):
for ex:
UIMyCustomTableViewCell.h
#interface UIMyCustomTableViewCell : UITableViewCell {
}
#property (nonatomic, retain) UILabel *label1;
#property (nonatomic, retain) UILabel *label2;
#property (nonatomic, retain) UILabel *label3;
#end
UIMyCustomTableViewCell.m
#implementation UIMyCustomTableViewCell
#synthesize label1 = _label1;
#synthesize label1 = _label2;
#synthesize label1 = _label3;
... init, memory cleanup, etc.
#end
At that point you can use that cell in your cellForRowAtIndexPath code:
if (cell == nil)
{
cell = [[UIMyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
CGRect labelFrame = cell.bounds;
labelFrame.size.height= labelFrame.size.height * 0.5;
cell.label1 = [[UILabel alloc] initWithFrame:labelFrame];
etc...
}
cell.label1.text = ...
cell.label2.text = ...
cell.label3.text = ...
I'm also a big fan of setting up look and feel of all customized cells in xib files instead of initializing labels in code like above, much cleaner in sizable apps.
Hope this helps.

How to change the background image of UITableView cell on a button click

In my UITableViewCell i have a UIButton and a label which is been dynamically added to the cell.
I have a background image for the cell too so when this button gets clicked i want either the background of the cell to get replace with another image or i want the text color of the label to change to something else like gray or blue.
Is that possible?
Here's the code for ny cellForRowAtIndexPath:
- (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:CellIdentifier];
NSArray *subviews = cell.contentView.subviews;
for (UIView *vw in subviews)
{
if ([vw isKindOfClass:[UILabel class]])
{
[vw removeFromSuperview];
}
}
NSArray * temp;
NSData * imageData;
if (dataToDisplay!=nil) {
temp = [dataToDisplay objectAtIndex:indexPath.row];
imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: [temp objectAtIndex:4]]];
}
playButtonImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"music_player_play_button.png"]];
pauseButtonImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"music_player_pause_button.png"]];
UIButton* preview = [UIButton buttonWithType:UIButtonTypeCustom];
preview.tag = 100 + indexPath.row;
[preview addTarget:self
action:#selector(playPreview:)
forControlEvents:UIControlEventTouchUpInside];
preview.backgroundColor = [UIColor clearColor];
preview.frame = CGRectMake(11,6, 36, 35);
[preview setBackgroundImage:playButtonImage.image forState:UIControlStateNormal];
[cell addSubview:preview];
UILabel * songName = [[UILabel alloc]initWithFrame:CGRectMake(60,15, 150, 15)];
songName.tag = 100+indexPath.row;
songName.text = [temp objectAtIndex:5];
songName.font = [UIFont boldSystemFontOfSize:12];
songName.backgroundColor = [UIColor clearColor];
[cell addSubview:songName];
UIButton * buy = [UIButton buttonWithType:UIButtonTypeCustom];
[buy addTarget:self
action:#selector(buySong:)
forControlEvents:UIControlEventTouchUpInside];
[buy setImage:[UIImage imageNamed:#"button_buy.png"] forState:UIControlStateNormal];
buy.tag = 200 + indexPath.row;
[buy setTitle:#"Buy" forState:UIControlStateNormal];
buy.titleLabel.font = [UIFont boldSystemFontOfSize:8.0];
buy.frame = CGRectMake(255,9,41, 30);
[cell addSubview:buy];
songsResults.tableHeaderView = headerView;
UIImage * cellIcon;
if (indexPath.row==[dataToDisplay count]-1) {
cellIcon = [UIImage imageNamed:[cellViewImages objectAtIndex:1]];
}
else {
cellIcon = [UIImage imageNamed:[cellViewImages objectAtIndex:0]];
}
cell.backgroundView = [[UIImageView alloc]initWithImage:cellIcon];
cell.clipsToBounds = YES;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Using the tag as an identifier of the cell whose button was pressed. That way you can determine which cell you need to change:
-(void)buySong:(id)sender {
UIButton *buttonPressed = (UIButton*)sender;
NSUInteger rowSelected = buttonPressed.tag - 200;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowSelected inSection:0];
CustomTableViewCell *cellSelected = (CustomTableViewCell)[self.tableView cellForRowAtIndexPath:indexPath];
cellSelected.label.textColor = [UIColor redColor];
}
You should subclass UITableViewCell so you can add new attributes to it and access them later on, like I did with CustomTableViewCell.
Here is a tutorial on how to create a custom UITableViewCell.
Cheers
I'd make a subclass of UITableViewCell that has its own action method to receive the button click, and use a block to handle that click so that your controller code could look something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SongCell *cell = [tableView dequeueReusableCellWithIdentifier:[SongCell identifier]];
if (cell == nil) {
cell = [[SongCell alloc] init];
}
cell.songData = [dataToDisplay objectAtIndex:indexPath.row];
cell.onPreviewClick =
^
(SongCell *cell)
{
cell.isPlaying = YES;
[self playSongAtIndexPath:indexPath]; // method to start the preview
};
return cell
}
To support this, your UITableViewCell subclass would look something like this:
// SongCell.h
#interface SongCell : UITableViewCell
#property (nonatomic, strong) NSArray *songData; // NSDictionary would be better
#property (nonatomic, copy) void(^onPreviewClick)(SongCell *cell);
#property (nonatomic, assign) BOOL isPlaying;
+ (NSString *)identifier;
#end
with this implementation:
// SongCell.m
#import "SongCell.h"
#interface SongData()
#property (nonatomic, strong) NSArray *_songData;
#property (nonatomic, assign) BOOL _isPlaying;
#property (nonatomic, strong) UIButton *playImage;
#property (nonatomic, strong) UIButton *pauseImage;
#property (nonatomic, strong) UIButton *previewButton;
#property (nonatomic, strong) UILabel *songNameLabel;
- (void)previewButtonPressed:(UIButton *)button;
#end
#implementation SongCell
#synthesize onPreviewClick, _songData, _isPlaying, playImage, pauseImage, previewButton, songNameLabel;
- (id)init {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[SongCell identifier]])) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.playImage = [UIImage imageNamed:#"music_player_play_button.png"];
self.pauseImage = [UIImage imageNamed:#"music_player_pause_button.png"];
self.previewButton = [UIButton buttonWithType:UIButtonTypeCustom];
previewButton.frame = CGRectMake(11,6, 36, 35);
[previewButton addTarget:self
action:#selector(previewButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:previewButton];
self.songNameLabel = [[UILabel alloc]initWithFrame:CGRectMake(60,15, 150, 15)];
songNameLabel.font = [UIFont boldSystemFontOfSize:12];
[self addSubview:songNameLabel];
}
return self;
}
+ (NSString *)identifier {
return #"SongCell";
}
- (void)setSongData:(NSArray *)songData
{
self._songData = songData;
[self updateSubviews];
}
- (NSArray *)songData {
return _songData;
}
- (void)setIsPlaying:(BOOL)isPlaying {
self._isPlaying = isPlaying;
[self updateSubviews];
}
- (BOOL)isPlaying {
return _isPlaying;
}
- (void)previewButtonPressed:(UIButton *)button {
if (onPreviewClick) onPreviewClick(self);
}
- (void)updateSubviews {
if (_isPlaying) {
[previewButton setBackgroundImage:pauseImage forState:UIControlStateNormal];
}
else {
[previewButton setBackgroundImage:playImage forState:UIControlStateNormal];
}
songNameLabel.text = [_songData objectAtIndex:5];
}
#end
Caveat: I didn't test this. Hopefully it doesn't have too many errors.

TableView with 2 colums by row , iphone/ipad

Can anybody tell me how to create a tableview
with two cells by colums in the Iphone SDK??
order in like this :
_____________
| 1 | 2 |
|_____|______|
| 3 | 4 |
|_____|______|
Best regards
In ios UITableView you can only have one column/cell. If you want more propertyes, in a same cell you need to create a custom table view cell by subcalssing UITableViewCell. In interface builder you can customize the layout. TUTORIAL: http://adeem.me/blog/2009/05/30/iphone-sdk-tutorial-part-6-creating-custom-uitableviewcell-using-interface-builder-uitableview/
Concrete example for your problem:
the .h file:
#import <UIKit/UIKit.h>
#interface MyCell : UITableViewCell {
UIButton * column1;
UIButton * column2;
UILabel* column1_label1;
UILabel* column1_label2;
UILabel* column2_label1;
UILabel* column2_label2;
}
#property (nonatomic,retain) UIButton * column1;
#property (nonatomic,retain) UIButton * column2;
#property (nonatomic,retain) UILabel* column1_label1;
#property (nonatomic,retain) UILabel* column1_label2;
#property (nonatomic,retain) UILabel* column2_label1;
#property (nonatomic,retain) UILabel* column2_label2;
#end
the .m file:
#import "MyCell.h"
#implementation MyCell
#synthesize column1,column1_label1,column1_label2,column2,column2_label1,column2_label2;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
column1 = [UIButton buttonWithType: UIButtonTypeCustom];
column1.tag = 1;
column1.autoresizingMask = 292;
column1.backgroundColor = [UIColor redColor];
column1.frame = CGRectMake(0, 0, self.contentView.bounds.size.width/2, self.contentView.bounds.size.height);
column1_label1 = [[UILabel alloc] initWithFrame: CGRectMake(column1.bounds.size.width*1/5,
0,
column1.bounds.size.width*4/5,
column1.bounds.size.height/2)];
column1_label1.backgroundColor = [UIColor redColor];
[column1 addSubview:column1_label1];
column1_label2 = [[UILabel alloc] initWithFrame: CGRectMake(column1.bounds.size.width*1/5,
column1.bounds.size.height/2,
column1.bounds.size.width*4/5,
column1.bounds.size.height/2)];
column1_label2.backgroundColor = [UIColor greenColor];
[column1 addSubview:column1_label2];
[self.contentView addSubview: column1];
column2 = [UIButton buttonWithType: UIButtonTypeCustom];
column2.tag = 2;
column2.autoresizingMask = 292;
column2.backgroundColor = [UIColor greenColor];
column2.frame = CGRectMake(self.contentView.bounds.size.width/2, 0, self.contentView.bounds.size.width/2, self.contentView.bounds.size.height);
column2_label1 = [[UILabel alloc] initWithFrame: CGRectMake(column2.bounds.size.width*1/5,
0,
column2.bounds.size.width*4/5,
column2.bounds.size.height/2)];
column2_label1.backgroundColor = [UIColor redColor];
[column2 addSubview:column2_label1];
column2_label2 = [[UILabel alloc] initWithFrame: CGRectMake(column2.bounds.size.width*1/5,
column2.bounds.size.height/2,
column2.bounds.size.width*4/5,
column2.bounds.size.height/2)];
column2_label2.backgroundColor = [UIColor greenColor];
[column2 addSubview:column2_label2];
[self.contentView addSubview: column2];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc
{
[super dealloc];
}
#end
the usage in UITableViewController:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 40;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
MyCell * mycell2 = ((MyCell*)cell);
if (cell == nil) {
cell = [[[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[mycell2.column1 addTarget:self action:#selector(column1Selected:) forControlEvents:UIControlEventTouchUpInside];
[mycell2.column2 addTarget:self action:#selector(column1Selected:) forControlEvents:UIControlEventTouchUpInside];
}
// Configure the cell...
mycell2.column1_label1.text = #"column1_label1";
mycell2.column1_label2.text = #"column1_label2";
mycell2.column1.tag = indexPath.row*2;
mycell2.column2_label1.text = #"column2_label1";
mycell2.column2_label2.text = #"column2_label2";
mycell2.column2.tag = indexPath.row*2 +1;
return cell;
}
- (void) column1Selected: (id) sender
{
UIAlertView *alert = [[ UIAlertView alloc]
initWithTitle: #" Alert"
message: [NSString stringWithFormat: #"button %d",((UIButton *) sender).tag]
delegate: nil
cancelButtonTitle: #" OK"
otherButtonTitles: nil];
[alert show] ;
[alert release];
}
In iOS6 you can use the UICollectionView.
If you need iOS5 support AQGridView is a grid control that will give you what you are after.