UICollectionViewCell shadow color - ios

In the new UICollectionView I do not see how to add a shadow to a UICollectionViewCell. How would I go about this. Would I add another view?
[self.collectionView cellForItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:[self view]]]].layer.shadowPath = [UIBezierPath bezierPathWithRect:rect].CGPath;
[self.collectionView cellForItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:[self view]]]].layer.shadowColor = [UIColor yellowColor].CGColor;
[self.collectionView cellForItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:[self view]]]].layer.shadowRadius = .5;
[self.collectionView cellForItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:[self view]]]].layer.shadowOpacity = .1;

You're forgetting to set masksToBounds on UIView to NO. This should work:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"PhotoCell" forIndexPath:indexPath];
cell.layer.masksToBounds = NO;
cell.layer.borderColor = [UIColor whiteColor].CGColor;
cell.layer.borderWidth = 7.0f;
cell.layer.contentsScale = [UIScreen mainScreen].scale;
cell.layer.shadowOpacity = 0.75f;
cell.layer.shadowRadius = 5.0f;
cell.layer.shadowOffset = CGSizeZero;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRect:cell.bounds].CGPath;
cell.layer.shouldRasterize = YES;
return cell;
}

[self.collectionView cellForItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:[self view]]]].layer.masksToBounds = NO;

most likely your problem is best solved with the existing answer to How do I draw a shadow under a UIView?
to be specific to your circumstance, you would probably have code that would do what the following code does (depending upon where you get your collectionView and someIndexPath in order to point to the cell you're interested in):
UICollectionViewCell* collectionViewCell
= [collectionView dequeueReusableCellWithReuseIdentifier:DEFINED_IDENTIFIER forIndexPath:someIndexPath];
collectionViewCell.layer.shadowPath = [UIBezierPath bezierPathWithRect:collectionViewCell.bounds].CGPath;
there are obviously other ways to get the cell. the important thing is the 2nd line, to set the shadowPath.

You are not setting the shadowOffset property on the layer.
myCell.layer.shadowOffset = CGSizeMake(10,10);

Go to the CustomCollectionviewCell.m and try to add this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//////// make shadow of total view
self.clipsToBounds = NO;
self.layer.masksToBounds = NO;
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOffset = CGSizeMake(0, 1);
self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
// make radius of the cell
self.layer.cornerRadius = 5;
}
return self;
}

Related

Removing a subview of UICollectionView cell content view crashes if that subview has a animated layer

I have added CABasicAnimation on a layer which is added as sublayer to a custom view.Custom view is then added to collection view cell content view as subview. I want to show indefinite progress like bar moving from left to right until download completes(please refer the attachments). Everything is fine except, once download is completed,For removing the custom view with layer animation, i cannot access that view using the tag. The compiler crashes and throws 'could not load any Objective-C class information. This will significantly reduce the quality of type information available'
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *attachDetail = [self getManagedObjectForIndexPath:indexPath];
ZCRMMailAttachmentCollectionViewCell *cell = (ZCRMMailAttachmentCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cellId" forIndexPath:indexPath];
[self setVisibilityOfRemoveButtonInCell:cell inObj:attachDetail];
[self setVisibilityOfSizeInCell:cell inObj:attachDetail];
cell.attachDetails = attachDetail;
[self addLoadingViewIfNotDownloaded:cell managedObject:attachDetail];
[cell redraw];
return cell;
}
-(void)addLoadingViewIfNotDownloaded:(ZCRMMailAttachmentCollectionViewCell*)cell managedObject:(NSDictionary*)attachDict
{
NSNumber *progress = attachDict[MAIL_ATTACH_DOWNLOAD_PROGRESS];
if(!ZV_IsEmpty(progress))
{
if (isinf([progress floatValue]))
{
[cell addLinearInfiniteProgress];
}
else
{
[cell removeLinearProgress];
}
}
}
-(void)addLinearInfiniteProgress
{
UIView* view = [zTvContentView viewWithTag:1234];
if(!view)
{
UIView *progressView = [UIView new];
progressView.tag = 1234;
progressView.layer.masksToBounds = YES;
[zTvContentView addSubview:progressView];
[progressView setBottom:-1];
[progressView alignTo:VTLayoutAlignLeft|VTLayoutAlignRight];
[progressView setHeight:2];
//ProgressLayer
CGRect frame = self.contentView.bounds;
CALayer * indeterminateLayer = [CALayer layer];
indeterminateLayer.delegate = self;
indeterminateLayer.name = #"progresslayer";
indeterminateLayer.frame = CGRectMake(0, 0, 0.4*CGRectGetWidth(frame), 3);
indeterminateLayer.backgroundColor = [CurTheme() themeActionItemColor].CGColor;
indeterminateLayer.opacity = 1;
[progressView.layer addSublayer:indeterminateLayer];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"position"];
animation.duration = 1;
animation.repeatCount = HUGE_VALF;
animation.removedOnCompletion = YES;
animation.fromValue = [NSValue valueWithCGPoint:CGPointMake( CGRectGetMinX(frame) - indeterminateLayer.frame.size.width + OFFSET, 0)];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(frame) + indeterminateLayer.frame.size.width - OFFSET, 0)];
[indeterminateLayer addAnimation:animation forKey:#"position"];
}
}
(void)removeLinearInfiniteProgress
{
UIView* progressView = [zTvContentView viewWithTag:1234];
if(progressView)
{
if ([progressView superview])
{
[progressView removeFromSuperview];
}
}
}
Any help would be appreciated.

iOS: UICollectionView Cell loading is very jerky

Im using UICollectionView for showing listing of images using SDWebImage which is very jerky and the scroll is not smooth. Any suggestions as to how do I proceed with this?
below is code in
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSString * cellIdentifier = #"offersCell";
HotDealsCollectionViewCell * cell = (HotDealsCollectionViewCell *)[self.productsCollectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
cell.layer.shadowColor = [[UIColor colorWithRed:210.0/255.0 green:210.0/255.0 blue:210.0/255.0 alpha:1.0] CGColor];
cell.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
cell.layer.shadowRadius = 3.0f;
cell.layer.shadowOpacity = 1.0f;
cell.layer.masksToBounds = NO;
CGRect shadowFrame = cell.layer.bounds;
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
cell.layer.shadowPath = shadowPath;
cell.backgroundColor = [UIColor whiteColor];
if ([self.productsArray count] > 0) {
Product * product = [self.productsArray objectAtIndex:indexPath.item];
cell.productName.text = product.productName;
cell.productEndDate.hidden = NO;
cell.productImageView.clipsToBounds = YES;
cell.productEndDate.textAlignment = NSTextAlignmentCenter;
[cell.productImageView sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://%#", product.productImage]] placeholderImage:[UIImage imageNamed:#"noProduct"]];
}
return cell;
}
Thats due to Image allocation, try the following
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
UIImage *image = [[UIImage imageWithCGImage:[list objectAtIndex:indexpath.row] thumbnailImage]];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
cell.imageView.image = image;
});
});
return cell;
}
if ([[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:url]]) {
[self.imageView setImage:[[SDWebImageManager sharedManager].imageCache imageFromDiskCacheForKey:url]];
} else {
[self.imageViewsd_setImageWithPreviousCachedImageWithURL:[NSURL URLWithString:url]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]
options:SDWebImageRefreshCached progress:nil
completed:nil];
}
try this
put below code in custom cell method
- (void)awakeFromNib
{
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
self.layer.shadowColor = [[UIColor colorWithRed:210.0/255.0 green:210.0/255.0 blue:210.0/255.0 alpha:1.0] CGColor];
self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
self.layer.shadowRadius = 3.0f;
self.layer.shadowOpacity = 1.0f;
self.layer.masksToBounds = NO;
CGRect shadowFrame = cell.layer.bounds;
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
self.layer.shadowPath = shadowPath;
self.backgroundColor = [UIColor whiteColor];
}
and remove this from -cellForItemAtIndexPath
try this

CollectionView Cell add 1px boarder become 2px

The designer need my each collectionView Cell have a 1px boarder,Like below:
And my implementation show,seem some border overlap and become 2px,Is there other easy way to get it done? Thanks for help.
Here is the main code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ServiceCategoryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"ServiceCategoryCollectionViewCell" forIndexPath:indexPath];
cell.entity = _categoryList[indexPath.row];
[cell.contentView addBorderWithWidth:0.5f hexColorString:#"#EFEFF4" cornerRadius:0];
return cell;
}
- (void)setupCollectionView{
UICollectionViewFlowLayout *flowFayout = [[UICollectionViewFlowLayout alloc] init];
flowFayout.scrollDirection = UICollectionViewScrollDirectionVertical;
flowFayout.minimumInteritemSpacing = 0;
flowFayout.minimumLineSpacing = 0;
flowFayout.itemSize = CGSizeMake(self.contentView.keyWindowWidth/4, self.contentView.height);
_categoryCollectionVIew.delegate = self;
_categoryCollectionVIew.dataSource = self;
_categoryCollectionVIew.scrollEnabled = NO;
_categoryCollectionVIew.collectionViewLayout = flowFayout;
[_categoryCollectionVIew registerNib:[UINib nibWithNibName:#"ServiceCategoryCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"ServiceCategoryCollectionViewCell"];
}
-(void)addBorderWithWidth:(float)width hexColorString:(NSString *)color cornerRadius:(CGFloat)cornerRadius{
self.layer.borderWidth = width;
self.layer.borderColor = [UIColor colorWithHexString:color alpha:1].CGColor;
self.layer.cornerRadius = cornerRadius;
self.layer.masksToBounds = YES;
}
Solution Of Overlapping CollectionView Cell Border:
add bottom and right side border through CALayer()
Objective c:
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor darkGrayColor].CGColor;
bottomBorder.frame = CGRectMake(0, cell.contentView.frame.height - 1,
cell.contentView.frame.width, 1);
[cell.layer.layer addSublayer:bottomBorder];
CALayer *rightBorder = [CALayer layer];
rightBorder.borderColor = [UIColor darkGrayColor].CGColor;
rightBorder.frame = CGRectMake(cell.contentView.frame.width, 0, 1,
cell.contentView.frame.height);
[cell.layer.layer addSublayer:rightBorder];
Swift :
let rightborder = CALayer()
rightborder.frame = CGRect(x:cell.frame.width - 1,y: 0, width: 1, height: cell.frame.height)
rightborder.backgroundColor = UIColor.darkGray.cgColor;
cell.layer.addSublayer(rightborder)
let bottomborder = CALayer()
bottomborder.frame = CGRect(x: 0, y: cell.frame.height - 1, width: cell.frame.width, height: 1)
bottomborder.backgroundColor = UIColor.darkGray.cgColor;
cell.layer.addSublayer(bottomborder)
I don't know its work but first try open simulator in fullscreen.
This is simulator problem, check you code in device and then compare.

How do i get custom UIView in table view cell

I have a Custom UIView inside my prototype cell in a nd iOS 8.2 app before it was a regular UIImage and i was getting it back fine with [currentCell viewWithTag:200]; inside my UITableView cellForRowIndexPath method. But after i have made a custom uiview and replaced the uiimage it always returns nil..
edit
After trying to add a new label to a working menu controller that is way more simple just loops over a array of strings. and setting the tag and in the loop (that is already printing the correct value out for the menu) it can't find the newly added label. is it possible to somehow not get the tags compiled ?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *currentCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Lists *listItem = [lists objectAtIndex:indexPath.row];
if(currentCell == nil){
currentCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//THIS ALLWAYS RETUNS nil
ShadedBadgeImage *cellImage = (ShadedBadgeImage *)[currentCell viewWithTag:200];
//UIView *cellImage = (UIView *)[currentCell viewWithTag:200];
//cellImage.completedProcentage = 2.0 * listItem.id.doubleValue;
UILabel *cellTitle = (UILabel *) [currentCell viewWithTag:101];
UILabel *cellDescription = (UILabel *)[currentCell viewWithTag:102];
cellTitle.text = listItem.id.stringValue;
cellDescription.text = listItem.shortText;
return currentCell;
And my custom uiview. that is using the layoutSubviews to render the masked image and progress bar.
IB_DESIGNABLE
#implementation ShadedBadgeImage {
double lineWidth;
CAShapeLayer *backgroundLayer;
CAShapeLayer *coloredLayer;
CALayer *imageLayer;
}
- (void)baseInit {
lineWidth = 5.0;
[self updateStroke];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self baseInit];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
//Adds the background ring layer
if(backgroundLayer == nil)
{
backgroundLayer = [[CAShapeLayer alloc] init];
CGRect rect = CGRectInset(self.bounds, lineWidth/2.0, lineWidth/2.0);
UIBezierPath *roundPath = [UIBezierPath bezierPathWithOvalInRect:rect];
backgroundLayer.path = roundPath.CGPath;
backgroundLayer.fillColor = nil;
backgroundLayer.lineWidth = lineWidth;
backgroundLayer.strokeColor = [UIColor colorWithWhite:0.5 alpha:0.05].CGColor;
[self.layer addSublayer:backgroundLayer];
}
backgroundLayer.frame = self.layer.frame;
//Adds the color ring layer
if(coloredLayer == nil)
{
coloredLayer = [[CAShapeLayer alloc] init];
CGRect rect = CGRectInset(self.bounds, lineWidth/2.0, lineWidth/2.0);
UIBezierPath *roundPath = [UIBezierPath bezierPathWithOvalInRect:rect];
coloredLayer.path = roundPath.CGPath;
coloredLayer.fillColor = nil;
coloredLayer.lineWidth = lineWidth;
coloredLayer.strokeColor = [UIColor blueColor].CGColor;
coloredLayer.anchorPoint = CGPointMake(0.5, 0.5);
coloredLayer.transform = CATransform3DRotate(coloredLayer.transform, -M_PI/2, 0, 0, 1);
[self.layer addSublayer:coloredLayer];
}
coloredLayer.frame = self.layer.frame;
//Adds the color ring layer
if(imageLayer == nil)
{
CAShapeLayer *imageMask = [[CAShapeLayer alloc] init];
CGRect insertBounds = CGRectInset(self.bounds, lineWidth + 3.0, lineWidth + 3.0);
UIBezierPath *innerPath = [UIBezierPath bezierPathWithOvalInRect:insertBounds];
imageMask.path = innerPath.CGPath;
imageMask.fillColor = [UIColor grayColor].CGColor;
imageMask.frame = self.bounds;
[self.layer addSublayer:imageMask];
imageLayer = [[CALayer alloc] init];
imageLayer.mask = imageMask;
imageLayer.frame = self.layer.frame;
imageLayer.backgroundColor =[UIColor grayColor].CGColor;
imageLayer.contentsGravity = kCAGravityResizeAspectFill;
[self.layer addSublayer:imageLayer];
}
[self updateStroke];
}
- (void) updateStroke{
if (coloredLayer != nil)
{
coloredLayer.strokeEnd = self.completedProcentage;
}
if(self.image != nil)
{
imageLayer.contents = (__bridge id)([self.image CGImage]);
}
}
#end
As the comments says, dont use tags go for custom UITableCellViews for more control

iOS - Shadow won't resize correctly

I have a tableView with dynamic cell sizes, and having trouble resizing the shadow when the cells are being reused. This solution works on iOS8 but not on iOS7. Also the shadows show up correctly based on the cell size the first time the shadow is create, but they break after cells are being reused.
#implementation
static const CGFloat shadowWithInset = 2;
static const CGFloat shadowHeightOutset = 4;
- (void)awakeFromNib {
CALayer *layer = self.innerView.layer;
layer.shadowOffset = CGSizeMake(1, 1);
layer.shadowRadius = 3.0f;
layer.shadowColor = [[UIColor gray] CGColor];
layer.shadowOpacity = 0.8f;
//layer.shouldRasterize = YES;
//layer.rasterizationScale = [UIScreen mainScreen].scale;
CGSize size = layer.bounds.size;
layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(shadowWithInset, size.height-shadowHeightOutset, size.width-(shadowWithInset*2), shadowHeightOutset)].CGPath;
}
- (void)layoutSubViews {
[super layoutSubviews];
CGSize size = self.innerView.bounds.size;
layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(shadowWithInset, size.height-shadowHeightOutset, size.width-(shadowWithInset*2), shadowHeightOutset)].CGPath;
}
#end
After populating all textfields in cellForRowAtIndexPath I ended up doing this:
[self setNeedsLayout];
[self layoutIfNeeded];

Resources