i have a simple uitableview with tableHeaderView. i have more than one section.
i set the headerview's height 30. but i want to use 40 pixel height uiview in my header (from 0,0 to 320,30 not transparent. from 30,10 to 320,40 is transparent). i put a picture in it. there is a small icon on point(0x30). its height=10.
i just want to show my headerview just a little bit over on the first tablecell.
you will see below that i set header's height to 30, but i create 40 pixel height view in viewForHeaderInSection.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *sectionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
sectionView.backgroundColor = [UIColor redColor];
[sectionView autorelease];
return sectionView;
}
is it possible?
Your sectionView will be limited by the height of header. Even if you use a UIView of 1000 pixels high, it will only be shown within the limits defined by the height of a table cell/header.
Maybe I have an answer for your problem. I don't know if this is a good solution but I think it is okay.
I made a new empty xib file and put a UITableViewCell in that file. I changed the height of the UITableViewCell to 54 and put a UIView inside the UITableViewCell. The frame of the view is 0,0,320,10. Then I changed the file's owner of that xib file to my TableViewController.
#interface RootViewController : UITableViewController {
UITableViewCell * firstCellInSection;
}
#property (nonatomic, retain) IBOutlet UITableViewCell * firstCellInSection;
#end
After that I connected the firstCellInSection Outlet with my UITableViewCell in the xib file.
Then I changed the code that the TableView loads this firstCell for all cells with
indexPath.row == 0
Here is the code:
#synthesize firstCellInSection;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell;
if (indexPath.row == 0) {
if (indexPath.row == 0) {
static NSString *firstCellInSectionIdentifier = #"FirstCellInSectionIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:firstCellInSectionIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"FirstCell" owner:self options:nil];
cell = firstCellInSection;
self.firstCellInSection = nil;
}
}
}
else {
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
}
// Configure the cell.
return cell;
}
Custom row height:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) return 54;
else return 44;
}
In combination with your code for the headerView it could look like you want.
Related
I want to add a view on selected cell of tableview. I'm writing this code.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIView *myView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 200)];
myView.backgroundColor=[UIColor greenColor];
myView.tag=1001;
[cell.contentView addSubview:myView];
}
after writing this code my other cells are not showing due to this view. I want to increase selected cell's height to 200 and add my custom view on selected cell.
can anyone tell me how to do this,,
thanks in advance.
Create a property of the selected cell
#property (nonatomic) int currentSelection;
Then initialize it here
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.currentSelection = -1;
}
In heightForRowAtIndexPath you can set the height you want for the selected cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
int rowHeight;
if ([indexPath row] == self.currentSelection) {
rowHeight = 200;
}
else
rowHeight = CURRENT_HEIGHT_HERE;
return rowHeight;
}
Then add you view here and hide it as:
// Customize the appearance of table view cells.
- (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] ;
}
UIView *myView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 200)];
myView.backgroundColor=[UIColor greenColor];
myView.tag=1001;
[myView setHidden:YES];
[cell.contentView addSubview:myView];
// Configure the cell.
return cell;
}
In didSelectRow you save the current selection and save a dynamic height, if required
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// do things with your cell here
// set selection
self.currentSelection = indexPath.row;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[[cell viewWithTag:1001] setHidden:NO];
// animate
[tableView beginUpdates];
[tableView endUpdates];
}
ok as i told u better u need to subclass the UITableViewCell in the following example, when selecting the cell it will add custom view to selected cell better u go through this and change it according to your requirement . Hope this helps u :)
//in subclassed cell "CustomCell.h" file
#interface CustomCell : UITableViewCell
{
UIView *aView; //to hold ur view
BOOL addView; //to check wheather to add view or not
}
#property(nonatomic, retain) UIView *aView;
#property(nonatomic, assign) BOOL addView;
#end
//in "CustomCell.m" file
#import "CustomCell.h"
#implementation CustomCell
#synthesize aView;
#synthesize addView;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
aView = [[UIView alloc]initWithFrame:CGRectZero]; //init the view with zero rect as if u want initially frame is zero
aView.backgroundColor = [UIColor greenColor]; //to know weather it is added or not
[self addSubview:aView];//added to cell
}
return self;
}
- (void)dealloc
{
[aView release];
[super dealloc];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
if(self.addView) //if the view is added
{
self.aView.frame = CGRectMake(10, 3, 100,200);
}
else
{
self.aView.frame = CGRectZero;//if there is no view
}
}
//in your ViewController.h file
#interface ViewController : UIViewController<CountdownTimerDelegate>
#property (retain, nonatomic) IBOutlet UITableView *aTableView;
#property (nonatomic, retain) NSIndexPath *selectedIndexPath;
#end
//in ViewController.m file
#import"CustomCell" //add this to header file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [self.aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell =[[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(self.selectedIndexPath != nil)
{
if(self.selectedIndexPath.row == indexPath.row)
cell.addView = YES;
else
cell.addView = NO;
}
//initially set it no for all cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//in did select row at indexpath
self.selectedIndexPath = indexPath;
[self.aTableView reloadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(self.selectedIndexPath != nil)
{
if(self.selectedIndexPath.row == indexPath.row)
{
return 200;
}
return 45;
}
else
return 45;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath.row;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
myView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 200)];
myView.backgroundColor = [UIColor greenColor];
myView.tag = 1001;
[cell.contentView addSubview:myView];
[tableView reloadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if ([indexPath row] == selectedIndex) {
return myView.bound.size.height;
}
else
return currentHeight;
}
Hope this will work.
I have a problem with a UITableView with custom UITableViewCell.
The table is filled by an NSArray, and I want that if an object in this NSArray begins with - changes its appearance.
the problem is that the UITableViewCell that begins with - is changed, but also change other cells that should not change.
this is my code:
//this is the way in which change the height of the cell if the object in the array begins with -
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *try = [arrayTitleEs objectAtIndex:indexPath.row];
if ([[try substringToIndex:1]isEqualToString:#"-"]) {
return 45;
}
else return 160;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellCardioScheda";
CardioSchedaCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.titleEs.text = [arrayTitoloEs objectAtIndex:indexPath.row];
NSString *try = [arrayTitoloEs objectAtIndex:indexPath.row];
if ([[try substringToIndex:1]isEqualToString:#"-"]) {
cell.titleEs.frame = CGRectMake(0, 0, cell.frame.size.width-15, cell.frame.size.height);
}
return cell;
}
as you can see from the picture that begins with the cell - is smallest and the text is moved to the left, in the next cell is all right, but the text in the last cell is moved, but should not!
thanks to all
In cellForRowAtIndexPath you can create two different types of cells and return one or the other according to your needs:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *firstCell = [tableView dequeueReusableCellWithIdentifier:#"firstCellID"];
if (firstCell == nil) {
firstCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"firstCellID"] autorelease];
}
// Set here firstCell
UITableViewCell *secondCell = [tableView dequeueReusableCellWithIdentifier:#"secondCellID"];
if (secondCell == nil) {
secondCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"secondCellID"] autorelease];
}
// Set here secondCell
if ([[try substringToIndex:1]isEqualToString:#"-"]) {
return secondCell;
} else {
return firstCell;
}
}
The problem is with the following:
if ([[try substringToIndex:1]isEqualToString:#"-"]) {
cell.titleEs.frame = CGRectMake(0, 0, cell.frame.size.width-15, cell.frame.size.height);
}
You need an else to set the frame properly if the condition isn't met. Cells get reused. Anything you do to a cell must be done for all cells.
if ([[try substringToIndex:1]isEqualToString:#"-"]) {
cell.titleEs.frame = CGRectMake(0, 0, cell.frame.size.width-15, cell.frame.size.height);
} else {
cell.titleEs.frame = CGRectMake(...); // whatever regular cells should be
}
BTW - you could replace [[try substringToIndex:1]isEqualToString:#"-"] with [try hasPrefix:#"-"].
I have created one uiviewcontroller with xib to adding in the uitableview cell. here is the code for that.
#interface CustomeCellHome : UIViewController{
IBOutlet UIImageView *imgViewBack;
// will have number of labels and imageviews.
}
#property (nonatomic, retain) UIImageView *imgViewBack;
#implementation CustomeCellHome
#synthesize imgViewBack;
all this IBOutlet connected to xib.
now i am adding this to my uitableview cell. here is code for that.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 150;
}
- (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];
// }
CustomeCellHome *objCell = [[CustomeCellHome alloc] init];
[objCell.view setTag:indexPath.row];
[cell.contentView addSubview:objCell.view];
objCell.imgViewBack.image = [UIImage imageNamed:#"unsel.png"];
[objCell release];
return cell;
}
now i want to change this imgViewBack image on selection of row. here is code for that.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CustomeCellHome *objCCell = [[CustomeCellHome alloc] init];
objCCell.view = [cell viewWithTag:indexPath.row];
objCCell.imgViewBack.image = [UIImage imageNamed:#"sel.png"];
}
but my imgViewBack is not changing its image. don't getting what is wrong with this. any suggestion for that ? any suggestion will be appreciated .
If you must use a viewController like u do (again probably this is not what u need), I can see few problems with your code.
1) Instead of [objCell.view setTag:indexPath.row]; use [objCell.view setTag:indexPath.row+1]; otherwise u will have a problem when indexPath.row=0 (I think 0 is also the tag of the superview).
2) Don't release the viewController, if u need one keep it around.
(but u will need to save it in some data structure so later u can release it...)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = nil;
// u will have problems reusing those cells...
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if(cell == nil)
// {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CustomeCellHome *objCell = [[CustomeCellHome alloc] init];
[objCell.view setTag:indexPath.row+1];
[cell.contentView addSubview:objCell.view];
objCell.imgViewBack.image = [UIImage imageNamed:#"image1.png"];
//[objCell release]; // don't release now, add it to some data structure so u can release later
// }
return cell;
}
2) Then in didSelectRowAtIndexPath retrieve the cell's viewController and change his imgViewBack property.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// get the cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// get the cell's viewController
UIView *aView = [cell.contentView viewWithTag:indexPath.row+1];
CustomeCellHome *objCCell = (CustomeCellHome *)[aView nextResponder];
// update the image
objCCell.imgViewBack.image = [UIImage imageNamed:#"image2.png"];
}
This will change the image, but this is not a perfect solution, u will have problems if u r reusing cells... Try rethink if u really need to use the viewController.
when adding an image to table cell, as default it goes to left:
cell.imageView.image = [UIImage imageNamed:[arrImages objectAtIndex:indexPath.row]];
how can I change it that every image in the UITableViewCell will go automaticlly to the right and the textLabel will be 10px to the left of the image.
Thanks alot!
Another way is to create a custom cell and override layoutSubviews method.
#interface CustomCell : UITableViewCell
#end
#implementation CustomCell
- (void)layoutSubviews
{
[super layoutSubviews];
// grab bound for contentView
CGRect contentViewBound = self.contentView.bounds;
// grab the frame for the imageView
CGRect imageViewFrame = self.imageView.frame;
// change x position
imageViewFrame.origin.x = contentViewBound.size.width - imageViewFrame.size.width;
// assign the new frame
self.imageView.frame = imageViewFrame;
}
#end
Rembember that in cellForRowAtIndexPath you need to create and reuse CustomCell and not UITableViewCell.
Hope it helps.
Edit
#import "CustomCell.h"
// other code here...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
Find the solution here code.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
cell.accessoryView = imageView;
For your reference.
UITableViewCell with image on the right?
try this:
cell.imageView.frame = CGRectMake(cell.frame.size.width - cell.imageView.frame.size.width, cell.imageView.frame.origin.y, cell.imageView.frame.size.width, cell.imageView.frame.size.height);
[cell.yourTexLabel sizeToFit];
cell.yourTexLabel.frame = CGRectMake(cell.imageView.origin.x - cell.yourTexLabel.frame.size.width - 10, cell.yourTexLabel.frame.origin.y, cell.yourTexLabel.frame.size.width, cell.yourTexLabel.frame.size.height);
Found a better answer from #TomSwift here https://stackoverflow.com/a/31616694/1884707
cell.contentView.transform = CGAffineTransformMakeScale(-1,1);
cell.imageView.transform = CGAffineTransformMakeScale(-1,1);
cell.textLabel.transform = CGAffineTransformMakeScale(-1,1);
cell.textLabel.textAlignment = NSTextAlignmentRight;
By applying a transform on the contentView you can place the imageView on the right.
in swift3 and swift4, we can use this:
cell.accessoryView = UIImageView(image:UIImage(named:"imageNmae")!)
One solution is to use a custom UITableViewCell. The steps are:
Create a new objective-C class that is a subclass of UITableViewCell, for example LabeledImageTableViewCell. Declare ivars and properties for a UILabel and a UIImageView.
In Interface Builder, set the content of the UITableView to Dynamic Prototypes. Drag a UIImageView and a UILabel to a table view cell and position them. Set the cell's class to LabeledImageTableViewCell. Connect the outlets of the cell to the UILabel & UIImageView objects of LabeledImageTableViewCell.
In the delegate for UITableView (usually a UITableViewController, sometimes a UIViewController) implement the datasource methods, for example:
//#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return (NSInteger)[rowData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"tvcLabeledImage";
LabeledImageTableViewCell *cell = (LabeledImageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[LNCCorrelationInfoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.myImage = [UIImage imageNamed:#"imageForThisRow.png"];
cell.myLabel = "imageForThisRow";
return cell;
}
Also, check out the Apple videos from WWDC 2011, UITableView Changes, Tips & Tricks and Introducing Interface Builder Storyboarding (Login required: https://developer.apple.com/videos/wwdc/2011/.)
I'm loading an image in to an UITableView through a simple
cell.imageView.image = [UIImage imageNamed:#"prem.jpg"];
However, what I've learnt from my limited time with xcode things arent normally that easy! I want to have the image in there take up the fullsize of the image which is about 280 wide and 150 tall. From googling I might have to build a custom cell and put the image in there and then load that custom cell? I've not done anything like that before and it seems a bit annoying just to load one image. Is there an alternative?
To put in context, I have 3 sections in the tableview top section will be the image, and the other two are arrays loaded from XML files. If I do a custom cell I have to do a seperate xml call to get the image url before it goes through so I'd really like to avoid that if possible?
Really looking for any pointers you can offer. Thanks a lot
Tom
Edit: cellforrowindexpath as requsted:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.section == 0)
cell.imageView.image = [UIImage imageNamed:#"prem.jpg"];
if(indexPath.section == 1)
cell.textLabel.text = [arryTableData objectAtIndex:indexPath.row];
else if(indexPath.section == 2)
cell.textLabel.text = [arryTableActions objectAtIndex:indexPath.row];
return cell;
}
There is no need to create a custom cell subclass. I am assuming you have a single cell in section 0 and a variable number of cells in sections 1 and 2.
You should be using a different cell reuse identifier for your cell in section 0 as it contains an image view and the others don't - this will show up in your later sections when the cells are recycled otherwise.
I'd try something like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifierText = #"TextCell";
static NSString *CellIdentifierImage = #"ImageCell";
if (indexPath.section == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierImage];
// I am assuming this image never changes and there is one row in this section! If it does change, use viewWithTag to get hold of the image view.
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierImage] autorelease];
UIImageView *myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,250,180)];
myImageView.tag = 1;
myImageView.image = [UIImage imageNamed:#"prem.jpg"];
[cell addSubview:myImageView];
[myImageView release];
}
return cell;
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierText];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierText] autorelease];
}
if(indexPath.section == 1)
cell.textLabel.text = [arryTableData objectAtIndex:indexPath.row];
else if(indexPath.section == 2)
cell.textLabel.text = [arryTableActions objectAtIndex:indexPath.row];
return cell;
}
}
Make sure you are adding the image to the newly created image view and not cell.imageView as the latter is a read-only property which is over to the left side, I'm not sure you can resize it.
You will also need to set the height for your cell, as it is taller than the standard. This will be in the tableView:heightForRowAtIndexPath: delegate method.
you can use the customCells.Means take an image view (whatever size you want.).And add it to the cell in cellforIndexpath method.