I want to customize my TableViewCell, it just fill with one image. And I tried to resize the frame of both the cell and my imageview, but when I run this program, I can't see my image on the screen.
Here is my code about the customer cell:
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self initLayout];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)initLayout {
self.imageView.frame = self.contentView.frame;
[self addSubview:_image];
}
- (void)resizeWithWidth:(NSInteger)width {
// I want the picture's width equal to the screen's, and the picture's height is 1/3 of its width
CGRect frame = [self frame];
frame.size.width = width;
frame.size.height = width / 3;
self.frame = frame;
self.imageView.frame = frame;
}
And in my TableViewController, I get the cell in this way:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
IntroductViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"introductcell" forIndexPath:indexPath];
// Configure the cell...
if (cell) {
cell = [[IntroductViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"introductcell"];
}
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
if (indexPath.row == 0) {
cell.imageView.image = [UIImage imageNamed:#"1.jpeg"];
} else if (indexPath.row == 1) {
cell.imageView.image = [UIImage imageNamed:#"2.jpeg"];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell resizeWithWidth:[UIScreen mainScreen].bounds.size.width];
return cell;
}
And, this is what I see when I run my program:
I noticed that for each cell, there is some space. How can I remove them?
I tried to remove the line: cell.selectionStyle = UITableViewCellSelectionStyleNone; in cellForIndex, and I found when click the second cell, it shows the image, but I still can not see the first image in the first cell, is there some relationship?
I see a couple of possible problems with the code, but I can't guarantee that this will solve the problem without more context.
1) You are using
- dequeueReusableCellWithIdentifier:forIndexPath: which requires that you have called either registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: (the first if you are using the interface builder, the second if you defined the cell in code only). I'm guessing you'll need the second one in your case. Example (this would be appropriate in your TableViewController's viewDidLoad):
[tableView registerClass: [IntroductViewCell class] forCellReuseIdentifier: #"introductcell"];
Sorry if my Objective-C is off a bit, I've been using Swift exclusively for the last year or so. If you already had this but left that part out of this question, then that's fine.
2) Get rid of this bit:
if (cell) {
cell = [[IntroductViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"introductcell"];
}
First of all, you probably wanted !cell there (or something like that). You probably didn't want to scrap the cell already there (you wanted a new one if there was none allocated, right? Not to re-allocate if the cell retrieval was successful). Second, it's no longer needed once you do the registerClass /
dequeueReusableCellWithIdentifier:forIndexPath: combo (in particular, the latter method will always return a valid cell).
The problem is with this line:
IntroductViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"introductcell" forIndexPath:indexPath];
Change it to:
IntroductViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"introductcell”];
To remove the separator line, use:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
Related
Hi i am new for ios and in my app i have created one UITableView and i have set background image for UITableViewcell but image not filling the whole width of screen as like below screen. Why this problem is occuring?
I mean UITableViewCell left and right sides gap is coming images is not filling whole cell width.
please help me someone
my code:-
#import "TableViewController.h"
#interface TableViewController ()
{
UITableView * tableList;
TableCell * Cell;
}
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
tableList = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, [[UIScreen mainScreen]bounds].size.height) style:UITableViewStylePlain];
tableList.delegate = self;
tableList.dataSource = self;
tableList.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:tableList];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"MyCell";
Cell = (TableCell *)[tableList dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (Cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:nil];
Cell = [nib objectAtIndex:0];
}
//UIImageView *imageBackground = [[UIImageView alloc] init];
if (indexPath.row == 0) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_top.png"];
} else if (indexPath.row == 9) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_bottom.png"];
} else {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_middle.png"];
}
//imageBackground.contentMode = UIViewContentModeScaleToFill;
//Cell.backgroundView = imageBackground;
return Cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 44.0;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#end
Try to set the layoutMargins property of the cells and the UITableView to UIEdgeInsetsZero.
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
tableList.layoutMargins = UIEdgeInsetsZero;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[...]
Cell.layoutMargins = UIEdgeInsetsZero;
return Cell;
}
Also check for the contentMode of the UIImageview.
Cell.backGroundImage.contentMode = UIViewContentModeScaleAspectFill;
try set contentInset on Left = 0
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
Use Debug View Hierarchy to figure out UITableView, UITableViewCell or UIImage is not filling the whole width of screen
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
Please check your "TableCell" in the storyboard. Did you select custom insets option for your custom cell?
Rather than setting up your table view with code, you want to do this in a storyboard. Then you'll want to use auto layout to connect constraints from the table view to the view controller's view. There are lots of tutorials available to teach you how to do this. Learning this will make things much easier in the long run.
Change the name of your tableList property to tableView. That will make more sense to other developers (including yourself in the future), since that's what it is (a UITableView instance).
Your cell is named Cell with a capital C, but you don't want to name properties with capital letters. Also, it doesn't need to be a class property the way it's being used. Remove it from the #interface section.
Coding Guidelines for Cocoa
Remove the -numberOfSectionsInTableView: method. The default is 1, so you don't need code to return the default value.
Instead of -dequeueReusableCellWithIdentifier:, use -dequeueReusableCellWithIdentifier:forIndexPath:. Then you won't need to follow it with a test to see if a cell was returned (it always will be). You'll need to register your nib with -registerNib:forCellReuseIdentifier:. Or better yet, just design it in the storyboard.
It appears that your custom table view cell has a UIImageView named backGroundImage. That should be added as a subview to the cell's backgroundView property (which you'll need to create - the view, not the property, which is already part of UITableViewCell). Set the image view's autoresizingMask so it will resize with the backgroundView:
- (void)awakeFromNib
{
[super awakeFromNib];
self.backgroundView = [[UIView alloc] initWithFrame:self.bounds];
self.backGroundImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backGroundImage.frame = self.backgroundView.bounds;
[self.backgroundView addSubview:self.backGroundImage];
}
Remove the -tableView:heightForRowAtIndexPath: method. You only want to use this if you return different values. The default row height is 44.0, so you don't need to do anything else.
I have a UITableView which I have transformed into horizontal tableview, and a custom UITableViewCell which just has a UIImageView and a UILabel
The problem is, first 5 cells don't show the images, but when I scroll and come back to them, images are shown. No idea what the problem is :(
(picture below, please see the horizontal tableview, ignore the vertical one)
Here's my code in TableViewController Class:
-(void)viewDidLoad
{
//Rotating the tableview angle -PI/2 Rad = -90 Degrees
_friendsTableView.transform= CGAffineTransformMakeRotation(-M_PI_2);
_friendsTableView.translatesAutoresizingMaskIntoConstraints = YES;
CGRect frame = _friendsTableView.frame;
frame.origin.y= _segmentControl.frame.size.height;
frame.origin.x= 0;
frame.size.width = self.view.frame.size.width;
frame.size.height = 105.5;
_friendsTableView.frame= frame;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FriendsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (nil == cell) {
cell = [[FriendsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
if(cell)
{
cell.user = cellsArray_[indexPath.row];
cell.transform =CGAffineTransformMakeRotation(M_PI_2);
}
return cell;
}
Now this is my custom cell class code where I set the image and label (_user is a property, so this setter method gets called automatically from cell.user):
-(void)setUser
{
_profileImageView.layer.cornerRadius = _profileImageView.frame.size.width/2;
_user = user;
_nameLabel.text = #"Hello";
[_profileImageView setImage:[UIImage imageNamed:#"placeholder_image"]];
}
Why dont you use Collection View controller instead. Transforming Tableview controller seems not good.
In your code your are not calling your setUser method.
For Custom table view cell you can add following code in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:strID];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
}
For my experience this is strictly related to the reusability of the Cells, i had a similar problem once, my solution is before assigning something to an IBOulet, make sure to have it empty, after that, assign it and it should work.
I have a UITableView with 10 cells.Except the first cell, all are the same.
Around 3 cells are displayed on screen at a time. Each cell has a label which says "Claim". Depending on certain events, I change the "claim" in SOME cells to "claimed".
Problem is when I scroll the cells , the some other cells (whose "claim" I haven't changed to "claimed") also show as "claimed". This seems random and feel is due to cell reuse and poor implementation. Please review the code and help me approach this better.
My requirement is :
Display 10 cells out of which all are identical except the first one.
All identical cells have a button / label with text "claim"
When I press the button , "claim" should change to "Claimed" ONLY for that particular cell in which the button resides.
This change should persist event when I scroll.
Custom cell used is :
#import "CustomSaloonCell.h"
#implementation CustomSaloonCell
#synthesize claimButton;
#synthesize delegateListener;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.claimButton=[UIButton buttonWithType:UIButtonTypeSystem];
self.claimButton.frame=CGRectMake(30,140,80, 30);
[self.claimButton setTitle:#"claim" forState:UIControlStateNormal];
[self.claimButton setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
self.claimButton.titleLabel.font = [UIFont fontWithName:#"Arial" size:(22)];
[self.claimButton addTarget:self action:#selector(claimButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:self.claimButton];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)claimButtonPressed{
[self.delegateListener didClickedClaimButton:self];
}
#end
The cell creation function :
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0){
CustomHeaderCell *headerCell = [[CustomHeaderCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"header_cell"];
headerCell.selectionStyle = UITableViewCellSelectionStyleNone;
return headerCell;
}
static NSString *cellIdentifier = #"HistoryCell";
// Similar to UITableViewCell, but
CustomSaloonCell *cell = (CustomSaloonCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomSaloonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.claimButton.tag = indexPath.row+TAG_OFFSET;
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"salon.jpg"]];
cell.delegateListener = self;
return cell;
}
The delegate method which modifies the label is :
- (void) claimConfirmedDelegate:(NSInteger)tag{
CustomSaloonCell *selectedCell=(CustomSaloonCell*)[self.claimTableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];
[selectedCell.claimButton setTitle:#"claimed" forState:UIControlStateNormal];
}
Save state of button (also title if your required) in separate instance mutable array.
When you pressed button and calling delegate method add that cell indexpath in your buttonStateArray.
Now check current indexPath in cellForRowAtIndexPath method: is containing buttonStateArray. If it present then change your button state and title yeah other thing if you want.
It will work after scrolling too.
Declare NSMutableArray *buttonStateArray; in .h file of tableview class.
Allocate it on initialization or after view loading.
- (void) claimConfirmedDelegate:(NSInteger)tag{
CustomSaloonCell *selectedCell=(CustomSaloonCell*)[self.claimTableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];
[selectedCell.claimButton setTitle:#"claimed" forState:UIControlStateNormal];
[buttonStateArray addObject:[NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];
}
Now in cellForRowAtIndexPath: method
for (NSIndexPath *selectedIndex in buttonStateArray){
if([selectedIndex isEqual:indexPath]){
//Change your state of button.
}
}
I created several cells with Interface Builder, and I'm using them to fill a UITableView. In other words, I have 3 classes for 3 different kinds of cell, and an other view which contains a UITableView.
- My UITableView containing different kinds of cells :
Here's my problem :
On the iPhone emulator, it looks great. But on the iPad emulator, the custom cells width is fixed. The UITableView width fits to the screen width, so it's good, but the UITableViewCells does not fit to the UITableView. I want to force the custom UITableViewCells to take the UITableView width.
Is there anything to do in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathmethod, where I instanciate my custom cells ?
Or do I have to write a thing like self.fitToParent; in the custom cells header file ?
EDIT (schema) :
EDIT 2 (cellForRowAtIndexPath method) :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifierType1 = #"cellType1";
static NSString *cellIdentifierType2 = #"cellType2";
NSString *currentObjectId = [[myTab objectAtIndex:indexPath.row] type];
// Cell type 1
if ([currentObjectId isEqualToString:type1])
{
CelluleType1 *celluleType1 = (CelluleType1 *)[tableView dequeueReusableCellWithIdentifier:cellIdentifierType1];
if(celluleType1 == nil)
celluleType1 = [[CelluleType1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierType1];
celluleType1.lblAuteur.text = #"Type1";
return celluleType1;
}
// Cell type 2
else if ([currentObjectId isEqualToString:type2])
{
CelluleType2 *celluleType2 = (CelluleType2 *)[tableViewdequeueReusableCellWithIdentifier:cellIdentifierType2];
if(celluleType2 == nil)
celluleType2 = [[CelluleType2 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierType2];
celluleType2.lblAuteur.text = #"Type2";
return celluleType2;
}
else
return nil;
}
}
I think uitableviewcell's width is the same as the tableview's width.You can try to set cell's background color to test it. cell.backgroundColor = [UIColor redColor] ;
You should create a class which inherit from UITableViewCell and override it's method - (void)layoutSubviews , adjust your content's frame there.
I resolved my problem using the following code in each custom cell class. It's not very clean, but I can't spend one more day on this issue...
- (void)layoutSubviews
{
CGRect contentViewFrame = self.contentView.frame;
contentViewFrame.size.width = myTableView.bounds.size.width;
self.contentView.frame = contentViewFrame;
}
Thank you for your help KudoCC.
- (void)awakeFromNib {
[super awakeFromNib];
// anything you write in this section is taken with respect to default frame of width 320.
}
awakeFromNib is called when [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; is processed- anything you write in section is taken with respect to default frame of width 320.
You need to make another custom function and call it after cell gets initialized.
For eg:-
#implementation CheckinTableViewCell{
UILabel *NameLabel;
UILabel *rollLabel;
}
- (void)awakeFromNib {
[super awakeFromNib];
NameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
rollLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:NameLabel];
[self.contentView addSubview:rollLabel];
}
-(void) bindView{
NameLabel.frame = CGRectMake(10, 10, self.contentView.frame.size.width-20, 20);
rollLabel.frame = CGRectMake(10, 30, NameLabel.frame.size.width, 20);
}
and call this function in tableview cellForRowAtIndex:-
-(UITableViewCell*) tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
CheckinTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell ==nil){
cell = [[CheckinTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.name = #"Harry";
cell.rollno = #"123456";
[cell bindView];
return cell;
}
-Hi, I have a problem with a tableview reloading data and what I want to do is that you put the selected cell in blue and change an image that is, the problem is that if I make the [self.mytableview reloadData] in the didselectedRow blue background disappears and if I do the image of the cell does not change, I'm a bit lost with this piece of code I give thanks
if (indexPath.row == _selectedRow) {
UIImageView *favView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"favIconSelected.png"]];
CGRect frame = favView.frame;
frame.origin.x = 294;
frame.origin.y = 7;
favView.frame = frame;
[cell.contentView addSubview:favView];
[favView release];
}
cell.selectedBackgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:SELCETED_BGIMGCELL]]autorelease];
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Product *p = [_productList objectAtIndex:indexPath.row];
_selectedRow=indexPath.row;
[_delegate productWasSelected:p];
[self.myTableView reloadData];
}
You don't need to call reloadData at all. All you need to do is to update the cell that was selected.
In the didSelectRowAtIndexPath method you can get the cell directly by calling cellForRowAtIndexPath on the tableView. This will return the actual cell that's on display and you can directly set the image it's displaying.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = ...;
Alternatively you could control the image display from your cell subclass if you provide it with both the normal and selected images when you configure each instance.