I am learning about UITableview on iOS and following a course online. I get the table showing fine, but the images on my cells are not all the way to the left (whereas the instructor's ones are). Here is a screenshot of the cells in question:
I don't want that gap, I want the images to be positioned right at the beggining of the cell, all the way to the left. I have done some research and it seems Apple has changed the default look of the cells between ios6 and ios7 so that now the images in cells show a little gap at the left. To get rid of it, I have tried UIEdgeInsets:
[tableView setSeparatorInset:UIEdgeInsetsZero];
and that's not working. I also have tried this approach:
cell.imageView.frame = CGRectMake( 0, 0, 50, 55 );
Nothing happens. So how would I go about it? Thanks
edit-------------------------------------------------------------------------------------------------------------------------------
Still not have found the answer to this. The solutions posted here don't work. I found this piece of code:
self.tableView.contentInset = UIEdgeInsetsMake(0, -50, 0, 0);
Which besides completely puzzling me (as the parameter affected should be the y?) I thought solved the issue by making the image on the cell appear all the way to the left, until I realised it only moved the whole view to the left (as I should have expected I guess) leaving an equal gap on the other side of the screen. All I want is for my images in the cells to appear all the way to the left of the cell as it used to be the case on previous ios. Thanks
It happens because default table content offset from left is 15, you should change it with 0.
See this once, you get idea Remove empty space before cells in UITableView
If you create custom cells. UITableViewCell have owner imageView. Change title of image in your cell.
If you use default cell, use custom cell with constraint Leading space = 0.
It is better not use default imageView of the cell. Drag and drop UIImageView from objective library, create a custom table view cell (Child class of UITableViewCell) then create and outlet of the image view just dragged.
The spacing in the UITableViewCell is because of the default TRUE returned by shouldIndentWhileEditingRowAtIndexPath method of UITableViewDelegate.
I was able to reproduce your problem by the below scenario:
UITableView is in editable mode:
self.tableView.editing = true
And you have implemented:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
To correct your code:
If you do not want to set Editing Style then you can turn off the editing mode by
self.tableView.editing = false
and remove editingStyleForRowAtIndexPath.
Else if you need editing mode then set the appropiate Editing style(UITableViewCellEditingStyleDeleteor UITableViewCellEditingStyleInsert) or simply turn the indentation off.
- (BOOL)tableView:(UITableView *)tableView
shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return FALSE;
}
You must create a custom cell, by adding a new class as a subclass of UITableViewCell. then you can design cell with autolayout and constraints which will resolve the issue.
there is a another concrete way to achieve this by creating subclass uitableviewcell (custom class).
steps to follow
create a class subclass of UITableViewCell.
in .h file create properties and outlets of UI components.
go to storyboard and add table view cell inside the tableview.
now add UI components like: imageview or button etc and set the x, y values according to.
make class of custom cell your className using identity inspector see image.
connect all outlets of UI components.
use below code uitableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *MyIdentifier = #"uniqueIdentifire";
yourCustomClassForCell *cell = (yourCustomClassForCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil){
cell = [[yourCustomClassForCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
cell.imageView.image = [imageAry objectAtIndex:indexPath.row];
}
Dont forget to give identifire by selecting your cell using storyboard Attribute inspector uniqueIdentifire to identifire property see image.
Also you can give some vertical space between cells by just to add this below code (Method only) inside customeCellClass.
- (void)setFrame:(CGRect)frame { // method to insert gap between table view cell
frame.origin.y += 6;
frame.size.height -= 2 * 6;
[super setFrame:frame];
}
You can not really change the frame of the inbuilt subviews of uitableviewcell like imageview, accessoryview. But if you create a custom tableviewcell class(even if you do not add any other subelement to it), you can change the frame of the inbuilt imageview by overriding the layoutSubviews method inside the UITableViewCell. I have tried it and it works.
#import "TableViewCell.h"
#implementation TableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void) layoutSubviews{
[super layoutSubviews];
CGRect frame = self.imageView.frame;
frame.origin.x = 0;
self.imageView.frame = frame;
}
#end
Related
I have UITableViewCell that contains UIView (lets call it CPView) which is created while cellForRowAtIndexPath is called. CPView is just a plain coloured view and for every cell its width is different (that's why needed to create in cellForRowAtIndexPath).
Problem is
1)The CPView 's colour gets darker every time cell loads (May be due to every time that cell creates the same view so overlapping effect).
2) The cell overlaps / inherits other cell's CPView (we can see this because of light and dark colour of two CPView).
How can I prevent cell to recreate if it already exist or creation of this CPView again?
Edit
- (void)configureCell:(CreditDebitCell *)cell atIndexPath:(NSIndexPath *)indexPath {
//other code
UIView * CPView;
if (CPView){
CPView =nil;
}
else
{
CPView = [[UIView alloc] initWithFrame:CGRectMake(cell.bounds.origin.x, cell.bounds.origin.y, cell.frame.size.width*[self.percentArray[indexPath.row] floatValue] ,cell.frame.size.height )];
[CPView setClipsToBounds:YES];
[CPView setBackgroundColor:[UIColor colorWithRed:107/255.0 green:15/255.0 blue:47/255.0 alpha:0.5]];
[cell addSubview: CPView];
}
}
The issue here is reuse of the cells - and therefore you get multiple views added to your cell view.
You can:
-remove subview
-check if subview exists and do/don't do anything.
You can check if the subview is there by going through subviews:
for (UIView *v in cell.contentView.subview) {
if ([v isKindOfClass:[CPView class]]) {
// remove or flag that it exists
}
}
But I think that you should handle this in your cell - not your view controller that implements table view delegate. Better tell cell to use some view/hide some view based on some kind of logic then to do that inside cellForRowAtIndexPath
According to your i question(without cellforRowAtIndexpath) i can assume that you should check every time something like in cellForRowAtIndexPath
if(cpView){
cpView = nil;
}
// alloc again with required size for particular row.
Make a subclass of your UITableViewCell and make a property of it that will reference your CPView. This will now let you have a better control whether your subclassed cell does / doesn't have any CPView that needs to be added.
As in the image below, the UITableView subview appears only on tableview reload or cell reuse (during scrolling, mostly). The blue color circle is what I want in my UITableViewCell. When it first appears, it will be a small dot as you can see in the picture, and on scrolling or refreshing the tableview, it appears as the full circle.
What can be the issue?
I use the following code in cellforRowAtIndexPath method
cell.categoryRoundBackground.layer.cornerRadius=cell.categoryRoundBackground.frame.size.height/2;
try using dequeueReusableCellWithIdentifier: forIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomTableViewCell *cell1 = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomID" forIndexPath:indexPath];
The most likely problem is that at the moment when you access your cell's frame height the first time by calling
cell.categoryRoundBackground.frame.size.height / 2
the cell has never been placed in a table view, it has no idea what its frame height is going to be, and so it uses some default value. The actual height depends on the value returned by your code in heightForRowAtIndexPath: method.
You can work around this problem by computing the frame size yourself. You should be able to do that, because your code supplies the value to heightForRowAtIndexPath:.
It's possible that you change the corner radius before that the view layouts its subviews.
You should try to put the line
cell.categoryRoundBackground.layer.cornerRadius=cell.categoryRoundBackground.frame.size.height/2;
inside
- (void)viewDidLayoutSubviews {}
You have to Override the method in CustomTableViewCell
- (void)layoutSubviews{
[super layoutSubviews];
self.categoryRoundBackground.layer.cornerRadius=self.categoryRoundBackground.frame.size.height/2;
self.categoryRoundBackground.layer.masksToBounds = YES;
}
and In CellForRowAtIndexPath: you have to write these lines at the end
// Update layout
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
Hope it will solve your problem
I receive a color from the server and in cellForRowAtIndexPath method I'm trying to apply this color to a view inside the cell.
The problem is that all the cells display the same color until I scroll down the table. When I start scrolling they update well their color.
I'm new on iOS and Objective-C, so if you could help me it would be appreciated, thanks.
Before scrolling:
After scrolling:
Some code: (If you want more please tell me)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CalendarDayCell *cell = (CalendarDayCell *) [tableView dequeueReusableCellWithIdentifier:#"CalendarDayCell"];
if (cell == nil) {
cell = [[CalendarDayCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CalendarDayCell"];
}
if (self.events.count) {
CalendarEvent *ce = self.events[indexPath.row];
CalendarDayCell *dayCell = (CalendarDayCell *) cell;
// ...
dayCell.viewColorBar.backgroundColor = [self colorWithHexString:ce.color];
return dayCell;
} else {
// Not important
}
}
PS: I've also tried it at willDisplayCell method with the same results.
EDIT:
Finally I figured out what were the solutions.
IDK why XCode redimensioned the color bar height to be 980px from the 50px that I specified in the nib file. And that was causing that all cells below had the same color.
I put all the views in another view, and assigned that view to the cell because some cells were not showing their color.
that's all
The problem is with reusing the cells - that means that in cellForRowAtIndex path you have to set color for every condition. This is easily reproducible with images. If you set image only sometimes, you will have to set image to none when you don't need to display it. What you need to do is to handle in the else block the control you want to change.
if(self.events.count){
dayCell.viewColorBar.backgroundColor = [self colorWithHexString:ce.color];
}
else{
dayCell.viewColorBar.backgroundColor = [UIColor clearColor];
}
Or something like that.
Are you sure that self.events.count is actually non-zero? Perhaps the tableview is being populated before self.events is setup properly.
For example, the view controller might be loading via viewDidLoad, then the UITableView, then you're setting self.events. If that's the case, self.events will be nil until the whole view/viewcontroller is loaded. That would account for it working after you start scrolling.
I am trying to create two status bars based on number of likes and dislikes. I want to resize the status bars for each cell. I am having trouble resizing the bars though. I have two ideas in mind on how to resize these bars.
I created UIViews and colored them red and green. I want to resize them, but I am unsure how to do this because Xcode doesn't allow me to access the size parameters.
cell.PositiveBar.layer.frame = CGRectMake(0, 0, 100, 100);
How can I have these status bars that change based on the likes and dislikes, looking for on a way to do this.
In case you have custom cell class, you need to add variables and connect them with views.
In cellForRow method you need to access to the Cell and config view's width, for that you can use layer or view, for example to change cell's status bar width:
- (void)setSellStatusBarByLikes:(NSInteger)likes
{
CGRect newFrame = self.positiveBar.frame;
// here you calculate width from likes count with your formula
newFrame.size.width = likes * dt;
[self.positiveBar setFrame:newFrame];
}
and for animation you need to wrap your setFrame method
[UIView animateWithDuration:.1f animations:^{
[self.positiveBar setFrame:newFrame];
}];
After this you can call this method from cellForRowClass
// In table view class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"HomeCell";
CustomTableViewCell *cell = [_p_leftTable dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell setSellStatusBarByLikes:10];
return cell;
}
EDIT
So you can do your custom class in storyboard, or upgrade UITAbleViewCell class with programatically added status bars. All next steps depends on your method.
When you declare variable inside your CustomTableViewCell as IBoutlet (if you do it through storyboard) or simple #property, it's already a part of CustomTableViewCell, then you can use it as self.something.
If you make this programmatically in default cell, then you just need to recreate your status bar views in cellForRow method.
i have some strange Problem. I use the Interface Builder to create a Custom TableCell with three Labels and one UIImageView:
I want that the Cell has a little space to the TableView (the blue border), so i put an extra View inside the Cell. As you can see the UIImageVIew is realy small and not higher than two labels, but when i run my code on the device the UIImageView is high as the white View and even covers the Label a little bit. The only thing i do in my Code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"CustomCellReuseID";
GTEventCustomCell *eventCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (eventCell == nil) {
eventCell = [[GTEventCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
}
// Configure the cell...
[eventCell.imageView setImage:[UIImage imageNamed:#"heart.png"]];
.
.
.
What´s wrong?
This will fix your problem:
eventCell.imageView.contentMode = UIViewContentModeScaleAspectFit;
I hope you have not missed the auto layout constraints for the objects inside the custom cell.
If not select a label/view
in toolbar Editor > Resolve Auto Layout issues > add missing constraints
and change the auto layout constraint as you need it.
I just think you should change your properties in the right panel.
You can also desactivate autolayout constraints and, to be sur to place your items at the good place, set them programmatically.
example :
at the top of your file :
#define X_Cell_Padding 10
#define Y_Cell_Padding 10
in cellForRow methods :
[[cell yourImageView] setFrame : CGRectMake(X_Cell_Padding, Y_Cell_Padding, yourImageView.frame.size.width, yourImageView.frame.size.height)];
don't forget to create a custom cell class with your IBOutlet yourImageView and to set this class for the cell in your storyboard / xib