Unable to create bottom border on UICollectionView Cell - objective-c

I need to add a 1px bottom border to my UICollectionView cells but I can't get it working, I tried the following code but the border doesn't show:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
cell.backgroundColor = [UIColor whiteColor];
cell.titolo.text = arrayt[prova];
//create the border
UIView *bottomBorder = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height, cell.frame.size.width, 1)];
bottomBorder.backgroundColor = [UIColor redColor];
[cell.contentView addSubview:bottomBorder];
return cell;
}
What could be the problem?
CGRectMake gets (x,y,width,height) as parameter so I can't understand what's wrong on my code

You need to have correct y offset
//create the border
UIView *bottomBorder = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height - 1, cell.frame.size.width, 1)];
bottomBorder.backgroundColor = [UIColor redColor];

You should set the frame of the cell to a known (not zero size) value before adding subviews like this. Then, after you have created your view with the correct frame you need to set the autoresizing mask to ensure that the view remains at the bottom of the view (flexible top, flexible width).

This is not the way to solve this, UIInsets are better way, as shown in this post: https://stackoverflow.com/a/22823146/12652 . But if you still want to follow this way, you need to remove these views afterwards or they will be kept adding to UICollectionViewCell. Considering you also have UIImageView as a childview :
UIView *bottomBorder = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height - 1, cell.frame.size.width, 1)];
bottomBorder.backgroundColor = [UIColor colorWithRed:162/255.0f green:143/255.0f blue:143/255.0f alpha:1.0f];
for(UIView *view in cell.contentView.subviews){
if([view isKindOfClass:NSClassFromString(#"UIImageView")])
continue;
else{
[view removeFromSuperview];
}
}
[cell.contentView addSubview:bottomBorder];

Related

Objective-C - UICollectionView with wrong indexpaths

I have a UICollectionView that I'm trying to use as a matrix with a first "column" used as the name of the row (colors) and then in the other items I put how many goods I'm buying. I had to split it in two collections because the header has to be fixed in that position.
My problem is that the initial situation is this:
Then, when I scroll the gray collection a bit and play with it...
The code which should manage the part is this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
CGSize cellSize = cell.frame.size;
int item = (int)indexPath.item;
int section = (int)indexPath.section;
NSLog(#"S:%d I:%d",section,item);
/*NSMutableArray *array = [matrice objectAtIndex:section];
if([array objectAtIndex:row] != [NSNull null]){
cell = [[matrice objectAtIndex:section] objectAtIndex:10-row];
return cell;
}else{
[[matrice objectAtIndex:section] replaceObjectAtIndex:row withObject:cell];
}*/
if(item == 0){ //Colori
int labelWidth = cellSize.width - 5;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((cellSize.width/2)-labelWidth/2, (cellSize.height/2)-labelWidth/2, labelWidth, labelWidth)];
Colore *colore = [cartellaColore.arrayColori objectAtIndex:section];
[label setText:colore.descrizione];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:14]];
[cell addSubview:label];
[cell setBackgroundColor:[UIColor whiteColor]];
}
else{
[cell setBackgroundColor:[UIColor grayColor]];
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
[cell addSubview:label];
return cell;
}
What am I doing wrong?
EDIT:
I let the program write different label on the same cell just for showing that the indexpaths are wrong. If they were correct it would just re-add the label in the same position with the same text (which I know is still wrong but it was just for debugging)
You can't add a label like that in your cellForRowAtIndexPath, you have to subclass a UICollectionViewCell.
I made a response to this kind of issue here : UICollectionView adding image to a cell
Just apply what I explained to a UILabel instead of a UIImageView, and your issues should disappear.
Let me know though.
This is your mistake:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
**[cell addSubview:label];**
you are stacking labels in cells, the cell are reusable, and each time you dequeue a reusable cell you add a label to it so if the dequeued cell has already been presented you will add another label to it and ect. You should protect your self from that by checking if that cell already has label and if it has than just change its text property, and if it doesn't do the code above... One way to do it is to add a specific tag to the label and then when you dequeue a cell just check if it has a view with that tag, if it has cast the view to label and change its text property so:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
if([cell viewWithTag:111]){
UILabel *label = (UILabe*)[cell viewWithTag:111];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
}
else{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
[label setTag:111];
[cell addSubview:label];
}
...

UITableViewCell and disappearing separator

I try to implement my own simple style of cells in my UITableView and I have a problem with separator. Works great with normal view, but when i select a cell it disappears. I try to add to my customSelect view separator, but then I can't see the separator anywhere. How can I add a separator to selected cell?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyCellIdentifier = #"MyCellIdentifier";
UITableViewCell *cell = [wallMenuTableView dequeueReusableCellWithIdentifier:MyCellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyCellIdentifier];
MenuItemModel *mItem = [menu.menuPositions objectAtIndex:indexPath.row];
cell.textLabel.text = mItem.displayName;
cell.textLabel.textColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.font = [UIFont fontWithName:#"ArialMT" size:16];
cell.textLabel.shadowColor = [UIColor blackColor];
cell.textLabel.shadowOffset = CGSizeMake(0.0, 1.0);
customSeparator = [[UIView alloc] initWithFrame:CGRectMake(0, (cell.frame.origin.y), 320, 2)];
customSeparator.backgroundColor=[UIColor blackColor];
[customSeparator.layer setShadowOffset:CGSizeMake(0.0, 0.8)];
[customSeparator.layer setShadowOpacity:0.8];
[customSeparator.layer setShadowRadius:0.8];
[customSeparator.layer setShadowColor:[UIColor grayColor].CGColor];
[cell.contentView addSubview:customSeparator];
customSelect = [[UIView alloc] initWithFrame:CGRectMake(0, (cell.frame.origin.y+2), cell.frame.size.width, cell.frame.size.height)];
//[customSelect addSubview:customSeparator];
customSelect.backgroundColor = [UIColor clearColor];
[cell setSelectedBackgroundView:customSelect];
}
return cell;
}
And current result:
Use a UIImageView instead of a simple UIView for your separator. Set the Image value (this is important!) instead of backgroundColor value and stretch the image with scale to fill.
Maybe your costumSelect is under the contentView of the Cell. I implemented such behaviour before, but I subclassed UITableViewCell. Try to override setSelected method on your custom cell.
use tableView.separatorColor (and tableView.separatorStyle) to set a contrasting separator color. If you're drawing your own separators within the cell, set separatorStyle=UITableViewCellSeparatorStyleNone. Furthermore, setting the selectionStyle to UITableViewCellSelectionStyleNone will likely help you

IOS UITableViewCell Spacer (or margin)

I'm trying to get a space between my table custom view cells on my table view controller. For example, for each cell created it is stacked up one by one and there is no margin. For example on the facebook iPhone app has a spacer after each cell which i would like to create, any ideas guys?
Edit: From comment below
The code looks like this
MSRSalesCompanyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.backgroundView = [[CustomCellBackground alloc] init];
NSDictionary *company = [companies objectAtIndex:[indexPath row]];
cell.companyName.text = [company objectForKey:#"Name"];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView.bounds = CGRectMake(0, 0, 320, 55);
[self loadImageAsync:cell withImageUrl:imageURL];
Check my answer for the similar question, it suggests you to create the invisible cells between the cells you want to divide with some space.
Option 2 is to create only the visible cells, make their height above the visible area and prepare special content and selected view's, note the selected view creation is not so easy and you'll need to do it as you probably don't want the spacing area to get selected, so i'm using the first option when there's a need to get some cell's spacing.
The main (and probably the only) disadvantage of the first option is that you have to treat the cell's indexes in a special way to distinguish the spacing-cells and the visible-cells.
If your tableView's rowHeight is 50 points, make your background image view height say, 40 points, and centre it in the cell. Then make your cell background colour [UIcolor clearColor]
Okayy i did some thing like this.....
First the BGColor Of view which will hold the Tableview is set to White (it was a personal choice w.r.t to my design) and then the cellForRowAtIndexPath method looks some thing like this.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
cell = nil;
//Create Cell
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//Retrive Values From DB
DBTable_Description *dbObject = [[DBTable_Description alloc]init];
dbObject = [contentList objectAtIndex:[indexPath row]];
//Cell View
UIView *cellView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 65)];
//ImageView
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(4.0, 8.0, 300.0, 58.0)];
imageView.userInteractionEnabled = NO;
imageView.image = imgForCellBkg;
//Label
UILabel *lblFor = [[UILabel alloc]initWithFrame:CGRectMake(70, 25, 200, 21)];
lblFor.text =dbObject.field1;
lblFor.backgroundColor = [UIColor clearColor];
lblFor.font = [UIFont fontWithName:#"Helvetica Neue" size:16];
lblFor.textColor = [UIColor grayColor];
lblFor.shadowColor = [UIColor grayColor];
//Adding Views to Cell View
[cellView addSubview:imageView];
[cellView addSubview:lblFor];
[cell.contentView addSubview:cellView];
cell.selectionStyle = NO;
return cell;
}
Okay First and formost neglect the Database code.
Now what i did is i created a View on each Cell name cellView (set the height as per ur requirement) next i had an Image View and set the appropriate image (again it may not be the thing u want to do) but pay attention to the CGRectMake i se the values according to the amount of gap i want b.w my cells.. the rest is usual.
here is the image of the view i had in my App
Let me Know if it worked
Cheers
W

How can I custom UITableViewCell like Twitter?

I found that the iPad twitter.app UITableViewCell's border have two pixel line, it looks beautiful and professional,how can I do that? Thank you!
Because UITableViewCell inherits from UIView, a cell has a content view. You can add your own subviews (the labels and textfields) to that contentView and lay them out programmatically or using the Interface Builder.
There are a lot of online tutorials on how to accomplish that. Just search with google for "uitableviewcell interface builder tutorial".
Check out this pretty good tutorial Custom UITableViewCell Using Interface Builder.
Finally,I customed UITableViewCell use code,and I think it looks well. : )
MenuViewController.m file:
- (id)initWithFrame:(CGRect)frame {
if (self = [super init]) {
[self.view setFrame:frame];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
[_tableView setDelegate:self];
[_tableView setDataSource:self];
[_tableView setBackgroundColor:[UIColor clearColor]];
[_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
UIView* footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)];
[_tableView setTableFooterView:footerView];
[footerView release];
[self.view addSubview:_tableView];
}
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
DoubleSeparatorCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[DoubleSeparatorCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
NSString *text;
UIColor *upperLineColor,*lowerLineColor,*viewColor;
upperLineColor = RGBA(255, 255, 255, 30);
lowerLineColor = RGBA(0, 0, 0, 50);
viewColor = RGBA(0,0,0,5);
if ([indexPath row] == 0) {
text = NSLocalizedString(#"...", nil);
} else if ([indexPath row] == 1) {
text = NSLocalizedString(#"...", nil);
} else if ([indexPath row] == 2) {
text = NSLocalizedString(#"...", nil);
} else {
text = NSLocalizedString(#"...", nil);
}
[cell.textLabel setText:text];
[cell.textLabel setTextColor:RGBA(170, 170, 170, 100)];
[cell.textLabel setShadowColor:[UIColor blackColor]];
[cell.textLabel setShadowOffset:CGSizeMake(1, 1)];
[cell.upperLine setBackgroundColor:upperLineColor];
[cell.lowerLine setBackgroundColor:lowerLineColor];
[cell.contentView setBackgroundColor:viewColor];
return cell;
}
DoubleSeparatorCell.h
#interface DoubleSeparatorCell : UITableViewCell {
UIView *upperLine;
UIView *lowerLine;
}
#property (nonatomic ,retain) UIView *upperLine;
#property (nonatomic ,retain) UIView *lowerLine;
#end
DoubleSeparatorCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.upperLine = [[UIView alloc] init];
self.lowerLine = [[UIView alloc] init];
[self.contentView addSubview:self.upperLine];
[self.contentView addSubview:self.lowerLine];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self.upperLine setFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 1)];
[self.lowerLine setFrame:CGRectMake(0, self.contentView.frame.size.height - 1, self.frame.size.width, 1)];
}
Srikar has already showed you the right path. By the way i just want to add the following:
You can cutomize your cell programmatically which can be done by inheriting the native class UITableViewCell.
Then by, create the instance of table view cell class and add it to the UITableView.
Now the cell is yours.
Happy Coding,
Arun
I'd point out that those cells you screenshot appear to have a light gray top border of 1 point and a dark gray bottom border of 1 point (or maybe they are pixels - sorry my eyes aren't that good :-) ).
So it may be kind of a hack (go on, savage me people), but you could:
Create a UILabel topBorder with frame CGRect(0,0,cell.contentView.frame.size,width,1)
Create a UILabel bottomBorder with frame CGRect (0,cell.contentView.frame.size.height - 1,cell.contentView.frame.size.width,1)
Set color of topBorder to UIColor lightGrayColor (or tweak for exact colors)
Set color of bottomBorder to UIColor darkGrayColor (ditto)
Add both subViews to cell.contentView
Note that you do not have to subclass UITableCellView - simply add these steps to your tableView:cellForRowAtIndexPath: method and they will appear.
Enjoy,
Damien
Override drawRect method and draw lines as you need.
- (void)drawRect:(CGRect)rect
{
CGRect bounds = [self bounds];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [topColor CGColor]);
// border top
CGContextMoveToPoint(context, bounds.origin.x, bounds.origin.y);
CGContextAddLineToPoint(context, bounds.origin.x+bounds.size.width, bounds.origin.y);
CGContextStrokePath(context);
// border bottom
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [lowerColor CGColor]);
CGContextMoveToPoint(context, bounds.origin.x, bounds.origin.y+1);
CGContextAddLineToPoint(context, bounds.origin.x+bounds.size.width, bounds.origin.y+1);
CGContextStrokePath(context);
}

How to create these kind of badges?

I sketched this prototype: http://dl.dropbox.com/u/3630641/3-%20Todolist%20Main.jpg
The number at the left is the item priority and list is re-orderable so the values will change. How to create these left-located badges? I prefer a code approach if possible, not PNG images.
Update:
Would you please have a look:
- (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];
CGRect priorityLabelRect = CGRectMake(10, 5, 20, 30);
UILabel *priorityLabel = [[UILabel alloc] initWithFrame:priorityLabelRect];
priorityLabel.layer.cornerRadius = 5.0f;
priorityLabel.layer.backgroundColor = [[UIColor grayColor] CGColor];
priorityLabel.tag = kPriorityValueTag;
[cell.contentView addSubview:priorityLabel];
[priorityLabel release];
CGRect meatLabelRect = CGRectMake(80, 5, 300, 30);
UILabel *meatLabel = [[UILabel alloc] initWithFrame:meatLabelRect];
meatLabel.tag = kMeatValueTag;
[cell.contentView addSubview:meatLabel];
[meatLabel release];
cell.showsReorderControl = YES;
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
But No grey area is shown around the priority.
If I add a new one, a grey area appears for less than a second around the priority but it disappears immediately. Not to mention that the priority value isn't located at the center for the grey area.
Any idea what I'm doing wrong?
Add a UILabel to the cell and format it to your liking. For the rounded corners, set label.layer.cornerRadius.
Create a UIView for the badge.
look here it will explaine how to draw what ever you want the badge to look like. and draw the number :
http://www.techotopia.com/index.php/An_iPhone_Graphics_Drawing_Tutorial_using_Quartz_2D
create a variable that will receive the cell number and draw it in the cell.
It should look something like that -
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect rectangle = CGRectMake(10,10,40,40);
CGContextAddRect(context, rectangle);
CGContextStrokePath(context);
CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor);
CGContextFillRect(context, rectangle);
CGPoint point =CGPointMake(20,20);
[self.cellNumber drawAtPoint:point withFont:font];
}
4 add the BadgeView to your cell and in the CellForRawAtIndexPath pass the number to the badge view.
good luck
You could make a combination control. It's a UIImageView with a UIImage and a UILabel as subviews.
A regular object that has a UIImageView.image with the gray rectangle and then a UILabel for the white number. Then just change the value of the label's text.
If you start with a UIImageView and subclass that, you will be able to just stick it directly into the regular UITableViewCells since they already have a space for a UIImageView.