I'm trying to use my ReusableCell for cells with images in different dimensions. The images are put inside a 220x150 black box with with scaling UIViewContentModeScaleAspectFit.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[cell.imageView setImage:[[UIImage alloc] initWithData:data]];
[cell.imageView setBackgroundColor:[UIColor blackColor]];
[cell.imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = cell.imageView.frame;
imageViewFrame.size.width = 220;
imageViewFrame.size.height = 150
[cell.imageView setFrame:imageViewFrame];
[cell.textLabel setText:item.title];
return cell;
}
The above code results in a layout like below and the images are sometimes changing when scrolling in the table view.
Instead of this unstructured layout, I would like the images to be aligned like this:
What am I doing wrong with this ReusableCell?
EDIT1:
I'm trying to create an imageView and add this imageView as a superview to cell.contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NewsItem *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
UIImage *placeholderImage = [UIImage imageNamed:#"ImagePlaceholderThumb"]; //220x150
UIImageView *imageView = [[UIImageView alloc] initWithImage:placeholderImage];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.imageUrl]];
[imageView setImage:[[UIImage alloc] initWithData:data]];
[imageView setBackgroundColor:[UIColor blackColor]];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
CGRect imageViewFrame = imageView.frame;
imageViewFrame.size.width = placeholderImage.size.width;
imageViewFrame.size.height = placeholderImage.size.height;
[imageView setFrame:imageViewFrame];
[cell.contentView addSubview:imageView];
[cell.textLabel setText:item.title];
return cell;
}
The above code results in the following:
It is like some of the images are visible in two cells. It seems that they are not keeping the size I've set in the imageViewFrame. Do you know why?
A quick fix would be using content mode UIViewContentModeScaleAspectFill. Images will be stretched in one or both dimensions to fill up the whole image view bounds.
You really need subclassing UITableViewCell to do this right.
Thre is a lazy solution adding a new UIImageView and using a spacer, as Keller told you in his answer (feel free to accept his answer, this is just the missing code).
Extract of tableView:cellForRowAtIndexPath::
...
cell.textLabel.text = [NSString stringWithFormat:#"Cell #%i", indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"spacer.png"]; /* spacer is 64 x 44 */
/* image view width should be ~ 64 px, otherwise it will overlap the text */
UIImageView *iv = [[UIImageView alloc] initWithFrame:(CGRect){.size={64, tableView.rowHeight}}];
switch (indexPath.row) {
case 0:
iv.image = [UIImage imageNamed:#"waterfall.png"];
break;
/* etc... */
}
if (indexPath.row < 3) {
/* add black bg to cell w/ images */
iv.backgroundColor = [UIColor blackColor];
}
iv.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:iv];
...
The table will look like this:
You need to set the placeholder (spacer.png above) in the existing cell image view. It will push the text label to the right.
You can use aspect fill and remove the background color bit:
iv.contentMode = UIViewContentModeScaleAspectFill;
The table will look wrong because the image is drawn outsite the bounds:
Just clip to bounds to get a better result:
iv.clipsToBounds = YES;
Create a UIImageView subview for each cell and it to the contentView. Each UIImageView contains an image with a consistent frame but with option UIViewContentModeScaleAspectFit. Then just Set the background color of the UIImageView to black.
I just confirmed this works, but you need to also create a placeholder spacer image to make sure the textLabel moves out of the way. Just make it the same dimensions of your image (with the letter boxing).
- (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];
//spacer
cell.imageView.image = [UIImage imageNamed:#"placeholder"];
//imageview
UIImageView *thumbnail = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 44)];
thumbnail.tag = kThumbTag;
thumbnail.backgroundColor = [UIColor blackColor];
thumbnail.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:thumbnail];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"Cell %d", indexPath.row];
cell.imageView.frame = CGRectMake(0, 0, 80, 44);
UIImageView *thumb = (UIImageView*)[cell.contentView viewWithTag:kThumbTag];
if (indexPath.row == 0) {
[thumb setImage:[UIImage imageNamed:#"image1.png"]];
} else {
[thumb setImage:[UIImage imageNamed:#"image2.png"]];
}
return cell;
}
Obviously, this example isn't lazy loading the images (I didn't realize you were loading them from a URL). For that, I would use a subclass with EGOImageView or something of the like.
Related
I'm working on a custom "Pulse style" UITableView according to this tutorial, and everything is going great. I've made some modifications and extensions but there is one feature I'd like to implement that I need some help with: the color of the horizontal bounce regions.
This is the method that creates my cell with a table view in it:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = [#"TableViewCell" stringByAppendingFormat:#"%i", self.content.indexInArrayOfViews];
UIView *view = [self.content viewAtIndex:indexPath.row];
UITableViewCell *cell = [self.horizontalTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease];
view.center = CGPointMake(view.center.y,view.center.x);
view.contentMode = UIViewContentModeCenter;
view.transform = CGAffineTransformMakeRotation(M_PI_2);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
[cell addSubview:view];
return cell;
}
I'm aware there is a reuse cell issue, but for right now I want to change this color here [IMG].
I can control the color of the vertical table view bounce areas, but I am having difficulty replicating this success for my horizontal view.
This is how I do it vertically:
CGRect frame = self.tableView.bounds;
frame.origin.y = -frame.size.height;
UIView* topBack = [[UIView alloc] initWithFrame:frame];
topBack.backgroundColor = [self.delegate backgroundColorForTopOfTableView];
[self.tableView addSubview:topBack];
[topBack release];
This was according to this StackOverflow question.
How do I change the color/background of my horizontal table view (which is nested in a table view cell)?
Here is an album with some relevant iPhone screenshots and IB screenshots.
I discovered a solution:
if (indexPath.row == 0){
UIView *bounce = [[UIView alloc] initWithFrame:CGRectMake(-320, 0, 320, 150)];
bounce.backgroundColor = [self.delegate colorForBounceRegionAtRow:self.content.indexInArrayOfViews];
[view addSubview:bounce];
}
if (indexPath.row + 1 == self.content.viewCount){
UIView *bounce = [[UIView alloc] initWithFrame:CGRectMake([self.content widthOfViewAtIndex:self.content.viewCount - 1], 0, 320*2, [self.content greatestHeight])];
bounce.backgroundColor = [self.delegate colorForBounceRegionAtRow:self.content.indexInArrayOfViews];
[view addSubview:bounce];
}
This adds a full screen's worth of colored rectangle to the first and last elements, giving the illusion of a bounce region.
I'm trying to add a dynamic horizontal scroll to a table cell.
I found an example after searching for a while, but since the example project only was the view it was directly connected to the app delegate which contained the majority of the relevant code. Most of it within applicationDidFinishLaunching.
Do any of you know how I am supposed to add this code to my project?
Thanks in advance, Tom
EDIT:
Here's the link to the sample project i downloaded: http://blog.sallarp.com/wp-content/uploads/2008/11/slidemenu.zip
Here's the youtube clip of how it's supposed to work: http://www.youtube.com/watch?v=wFqBNXZ4SHI
EDIT 2 (New code):
"famorables" is declared with 5 one-word-strings
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyFamorablesCell";
UITableViewCell *cell;
//Create Cell
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Create a UIScroll View
UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 80)];
scrollview.contentSize = CGSizeMake(self.view.frame.size.width * 2, 80);
scrollview.showsHorizontalScrollIndicator = NO;
float totalButtonWidth = 0.0f;
famorableArray = self.famorables;
for(int i = 0; i < [self.famorables count]; i++){
UIButton *famorableButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[famorableButton setFrame:CGRectMake(0.0f, 0.0f, 100.0f, 30.0f)];
[famorableButton setTitle:[NSString stringWithFormat:#"%#", [famorableArray objectAtIndex:[indexPath row]]] forState:UIControlStateNormal];
// Move the buttons position in the x-demension (horizontal).
CGRect btnRect = famorableButton.frame;
btnRect.origin.x = totalButtonWidth;
[famorableButton setFrame:btnRect];
// Add the button to the scrollview
[scrollview addSubview:famorableButton];
// Add the width of the button to the total width.
totalButtonWidth += famorableButton.frame.size.width;
}
[cell.contentView addSubview:scrollview];
return cell;
}
Okay Try this
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
//Create Cell
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//Create a UIScroll View
UIScrollView scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, (it will be the height of the Cell u want))];
scrollview.contentSize = CGSizeMake(self.view.frame.size.width * 2,(it will be the height of the Cell u want));
scrollview.showsHorizontalScrollIndicator = NO;
/*
Now add every this u might want to add in ur Scroll view.
keep that in mind that the height and width of contentSize and ScrollView will be depandent on ur requirement
Make sure u add every thing u want in the Scroll view will be the part of Scroll View
like for label
//Add Something to Scroll View
[scrollView addSubview:label];
*/
//Add Scroll view to Cell
[cell.contentView addSubview:scrollView];
return cell;
}
This will Work
In case of any queries feel free to ask
I'm trying to display a UIImageView inside a UITableViewCell.
Inside method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath I have:
- (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];
}
CGSize cellSize = cell.frame.size;
CGFloat cellWidth = cellSize.width;
CGFloat cellHeight = cellSize.height;
CGRect imageFrame = CGRectMake(0, 0, 70, cellHeight);
UIImageView * image = [[UIImageView alloc] initWithFrame:imageFrame];
[image setImage:[UIImage imageWithContentsOfFile:#"cyan.jpg"]];
CGRect nameFrame = CGRectMake(80, 0, cellWidth-80, cellHeight/2);
UILabel * nameLabel = [[UILabel alloc] initWithFrame:nameFrame];
nameLabel.text = #"Name: John Doe";
CGRect jobFrame = CGRectMake(80, 20, cellWidth-80, cellHeight/2);
UILabel * jobLabel = [[UILabel alloc] initWithFrame:jobFrame];
jobLabel.text = #"Job: IT-Consultant";
[cell addSubview:image];
[cell addSubview:nameLabel];
[cell addSubview:jobLabel];
return cell;
}
The labels are displaying perfectly but I don't see the image.
Any help would be appreciated.
imageWithContentsOfFile: expects a path to be sent to it. Use imageNamed: instead, or get hold of the path first by using NSBundle's pathForResource... methods first to get the path.
Also, if the image is the same for every cell, you should add the image view inside the cell=nil block, or you will be adding the view over and over again.
Add it to the UITableViewCell contentView instead.
[cell.contentView addSubview:...];
Use the UITableViewCell's imageView property instead of what you're doing. To be more clear, use cell.imageView.image and set your UIImage to that.
Or if you wish the image's location to be more flexible, add the imageView to the cell's contentView. i.e: [cell.contentView addSubview:yourImageView];
I have a UITableView that gets information from a server and publishes the data into a table view. Inside of each cell is the information from the server.
For the purpose of this example, let's say the information we get from the server are numbers: 1, 2, 3, 4.
What I want to do is add an image (programmatically because there are if statements involved, etc) to the left side of the cell, and the text (1, 2, etc) right next to it.
Basically, I want each cell to look like this:
_____________________________________
| (IMAGE) (TEXT) | --CELL 0
--------------------------------------
_____________________________________
| (IMAGE) 2 | --CELL 1
--------------------------------------
Please excuse my crude illustration. :)
here you go:
cell.imageView.image = [UIImage imageNamed:#"image.png"];
Swift:
cell.imageView?.image = UIImage(named: "image.png")
You can add both the image and the text to the UITableViewCell in your UITableViewController subclass like so:
- (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] autorelease];
}
[[cell imageView] setImage:anImage];
[[cell textLabel] setText:[NSString stringWithFormat:#"%d",[indexPath row]];
return cell;
}
There are a few "built-in" properties to UITableViewCell that you can take advantage of, such as the imageView, textLabel, and detailTextLabel. For more information, check out the Table View Programming Guide.
The Swift 2.0 version of the first answer is:
cell.imageView?.image = UIImage(named: "image.png")
UITableViewCell objects have an imageView property; you can just set this image view's image and it will automatically display the image in the right place with the title next to it.
// create a rectangle box for image view
UIImageView *iconImage = [[UIImageView alloc] init];
iconImage.frame = CGRectMake(12,4,53.5,53.5);
// Create a label for cells
UILabel *cellName = [[UILabel alloc] initWithFrame:CGRectMake(75,18,200,20)];
cellName.font = [self fontForBodyTextStyle];
NSString *cellNameStr = [NSString stringWithFormat:#"%#",self.tableCellNames[indexPath.row]];
// Select path row tab actions
switch (indexPath.row) {
case 0:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"condition.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 1:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"videos.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 2:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"provider.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
case 3:
cellName.text = cellNameStr;
iconImage.image = [UIImage imageNamed:#"info.png"];
[cell.contentView addSubview:iconImage];
[cell.contentView addSubview:cellName];
break;
default:
NSAssert(NO, #"Unhandled value in cellForRowAtIndexPath");
break;
}
I'm trying to add an extra UILabel into each cell(UITableView)
I'v succeeded with this code in
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
Here's my code
//add another text
UILabel *test = [[UILabel alloc] initWithFrame:CGRectMake(250,80,50,20.0)];
test.text = [NSString stringWithFormat: #"test"];
test.backgroundColor = [UIColor clearColor];
test.font=[UIFont fontWithName:#"AppleGothic" size:20];
[cell addSubview:test];
However I figured that if I do this, I can't add different text to each cell, instead, it ends up with the same text in all cells. Can anyone tell me how to do that?
Oh and another problem was that if I do this, "test" is displayed in every cell except for the first one.
Have a look at the tutorial "UITableView – Adding subviews to a cell’s content view".
Try something like this
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 320, 65);
CGRect Label1Frame = CGRectMake(17,5,250,18);
UILabel *lblTemp;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
[lblTemp setFont:[UIFont fontWithName:#"Arial-BoldMT" size:15]];
lblTemp.tag = 1;
lblTemp.backgroundColor=[UIColor clearColor];
lblTemp.numberOfLines=0;
[cell.contentView addSubview:lblTemp];
return cell; // this I forgot
}
in cellForRowAtIndexPath
{
if(cell == nil)
cell = [self getCellContentView:CellIdentifier];
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
lblTemp1.text =[nameArray objectAtIndex:value+indexPath.row];
return cell;
}
For having the same Label on all cells, you are probably instantiating just one cell and use the cellReUseIdentifier for all cells. So, I suggest that you create different labels as properties of the class, and assign each property-label to each cell.
// For example -
if (indexPath.row ==0 )
// assign [cell.contentView addSubview: self.label1];
if (indexPath.row ==1 )
// assign [cell.contentView addSubview: self.label2];
And for the second part of the question, please post your cellForRowAtIndexPath fully - there could be an error in that.
First check if any of the predefined styles work for you.
If you need more flexibility than what they offer, you can try something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [self makeCell: CellIdentifier];
}
MyData *data = [self.data objectAtIndex:indexPath.row];
UILabel *lbl1 = (UILabel *)[cell viewWithTag:1];
UILabel *lbl2 = (UILabel *)[cell viewWithTag:2];
lbl1.text = data.text;
lbl2.text = data.auxText;
return cell;
}
- (UITableViewCell *)makeLensListCell: (NSString *)identifier
{
CGRect lbl1Frame = CGRectMake(10, 0, 140, 25);
CGRect lbl2Frame = CGRectMake(10, 150, 140, 25);
UILabel *lbl;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier] autorelease];
// Label with tag 1.
lbl = [[UILabel alloc] initWithFrame:lbl1Frame];
lbl.tag = 1;
[cell.contentView addSubview:lbl];
[lbl release];
// Label with tag 2.
lbl = [[UILabel alloc] initWithFrame:lbl2Frame];
lbl.tag = 2;
lbl.textColor = [UIColor lightGrayColor];
[cell.contentView addSubview:lbl];
[lbl release];
// Add as many labels and other views as you like
return cell;
}
This approach also allows images and other views.