CollectionView Cell add 1px boarder become 2px - ios

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.

Related

UITextView border for each line

I'm developing an application, which has textView with bottom borders for each line, I can't find any answers on this question on google and on StackOverflow. So i decided i'll ask a question, i have this textview:
and i want it to look like this:
I'm doing it programmatically so please don't give me storyboard examples, Thank you
var textview:UITextView=UITextView()
for var i:Int = 20 ; i <= Int(textview.frame.size.height) ; i = i + 20 // set 20 you line distance .. change your chooice
{
let border = CALayer()
border.borderColor = UIColor.grayColor().CGColor
border.frame = CGRectMake(0, CGFloat(i), textview.frame.size.width*1.5 , 1.0)
border.borderWidth = 1.0
textview.layer.addSublayer(border)
textview.layer.masksToBounds = true
}
You Can Use this code
-(void)setBorderView:(UITextField*)textField
{
UIView *borderView = [[UIView alloc]init];
borderView.backgroundColor = [UIColor clearColor];
CGRect frameRectEmail=textField.frame;
NSLogVariable(textField);
borderView.layer.borderWidth=1;
borderView.layer.borderColor=[customColor colorWithHexString:#"8c8b90"].CGColor;
borderView.layer.cornerRadius=5;
borderView.layer.masksToBounds=YES;
UIView *topBorder = [[UIView alloc]init];
topBorder.backgroundColor = [customColor colorWithHexString:#"1e1a36"];
CGRect frameRect=textField.frame;
frameRect.size.height=CGRectGetHeight(textField.frame)/1.5;
topBorder.frame = frameRect;
frameRectEmail.size.width=frameRect.size.width;
[borderView setFrame:frameRectEmail];
[_textFieldBackGroundView addSubview:borderView];
[_textFieldBackGroundView addSubview:topBorder];
[_textFieldBackGroundView addSubview:textField];
}

iOS: one itemSpace of uicollectionView is 1px but another is 2px, I want the two all 1px?

I have a collectionView, in 1 and 2 section I want every itemSpace and lineSpace to be 1px, but the second itemSpace is always 2 px, this is screenshot, I have set collectionView's backgroundColor red, it looks more clearly.
this is screenshot
I set the minimumLineSpacing, minimumInteritemSpacing and itemSize like this:
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
float sortaPixel = 1.0/[UIScreen mainScreen].scale;
NSLog(#"minimumLineSpacing%f", sortaPixel);
return sortaPixel;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
float sortaPixel = 1.0/[UIScreen mainScreen].scale;
NSLog(#"minimumInteritemSpacing%f", sortaPixel);
return sortaPixel;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.section == 0){
if(ISBIND){
return CGSizeMake(SCREEN_WIDTH, finalTopheight);
}
return CGSizeMake(SCREEN_WIDTH, defaultTopheight);
}
//This is the calculation process
float sortaPixel = 1.0/[UIScreen mainScreen].scale;
NSLog(#"sizeForItem%f", sortaPixel);
CGFloat itemW = (self.collectionView.frame.size.width - sortaPixel * 2)/3.0;
CGFloat itemH = 106;
return CGSizeMake(itemW, itemH);
}
anyone can help me, give me some ideas, I am very grateful.
A combination of having to describe the problem here and a bit of
subsequent thought caused me to realize that although
minimumInteritemSpacing is a CGFloat it doesn't make sense to pass it
fractional values and its behaviour when you do so is undefined.
This is because, on devices where there's a 1:1 point to pixel ratio,
there is no such thing as half a pixel. It just so happened that in
some cases it behaved as I expected and thus blinded me to the real
(and rather obvious) problem.
Hopefully reading this can help others quickly realize the mistake.
See the post to know Float and CGFloat,
Changing an Int to a CGFloat in Swift to return heightForRowAtIndexPath tableview function
// AdselecterNamed top border in a view
+ (void)addTopBorderWithColor:(UIView *)view color:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];
border.frame = CGRectMake(0, 0, view.frame.size.width, borderWidth);
border.tag = 1000;
[view addSubview:border];
}
// Add bottom border in a view
+ (void)addBottomBorderWithColor:(UIView *)view color:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
border.frame = CGRectMake(0, view.frame.size.height - borderWidth, view.frame.size.width, borderWidth);
border.tag = 1001;
[view addSubview:border];
}
// Add left border in a view
+ (void)addLeftBorderWithColor:(UIView *)view color:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
border.frame = CGRectMake(0, 0, borderWidth, view.frame.size.height);
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin];
border.tag = 1002;
[view addSubview:border];
}
// Add right border in a view
+ (void)addRightBorderWithColor:(UIView *)view color:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin];
border.frame = CGRectMake(view.frame.size.width - borderWidth, 0, borderWidth, view.frame.size.height);
border.tag = 1003;
[view addSubview:border];
}

Add Border to the bottom of SELECTED segmented control

I am trying to add a border to the selected segmented control. Currently, I have code which sets the border of 3px to the bottom of the whole segmented control:
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
bottomBorder.frame = CGRectMake(0, self.segmentedControl.frame.size.height - bottomBorder.borderWidth, self.segmentedControl.frame.size.width, bottomBorder.borderWidth);
[self.segmentedControl.layer addSublayer:bottomBorder];
However, I want to add this border ONLY to the selected segmented control. How do I do this?
You can use the following code to dynamically add the selection:
// Removing previous selection
[bottomBorder removeFromSuperlayer];
// Creating new layer for selection
bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.selectedSegmentIndex * width;
CGFloat y = self.segmentedControl.frame.size.height - bottomBorder.borderWidth;
bottomBorder.frame = CGRectMake(x, y,width, bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:bottomBorder];
You need to remove the previous selection when new choice is selected, for that purpose make the bottomBorder layer as a member variable.
I converted the Objective-C solutions into swift3 it is working for me, My Segment controller width is equal to View width
#IBAction func SegmentAction(_ sender: UISegmentedControl) {
self.segmentBottomBorder?.removeFromSuperlayer()
self.segmentBottomBorder = CALayer()
self.segmentBottomBorder?.borderColor = UIColor.red.cgColor
self.segmentBottomBorder?.borderWidth = 3
let width: CGFloat = sender.frame.size.width/CGFloat(sender.numberOfSegments)
let x = CGFloat(sender.selectedSegmentIndex) * width
let y = sender.frame.size.height - (self.segmentBottomBorder?.borderWidth)!
self.segmentBottomBorder?.frame = CGRect(x: x, y: y, width: width, height: (self.segmentBottomBorder?.borderWidth)!)
sender.layer.addSublayer(self.segmentBottomBorder!)
}
This might not be the proper way, but you can give it a shot.
At the time you load the segment control, try this in viewdidload, so the layer gets added according to the selectedsegment button
if (self.segmentedControl.selectedSegmentIndex==0) {
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
bottomBorder.frame = CGRectMake(0, self.segmentedControl.frame.size.height - bottomBorder.borderWidth, self.segmentedControl.frame.size.width/2, bottomBorder.borderWidth);
[self.segmentedControl.layer addSublayer:bottomBorder];
}else if (self.segmentedControl.selectedSegmentIndex==1){
//change the border layer frame
} else if (self.segmentedControl.selectedSegmentIndex==2){
//change the border layer frame
}
Again in the segmentcontrol action method, you can alter these changes
//Connect action to segmented control.
- (IBAction)segmentedControlAction:(id)sender {
if(segmentedControl.selectedSegmentIndex == 0)
{
NSLog(#"First Segment (Feed) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.selectedSegmentIndex * width;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
else if(segmentedControl.selectedSegmentIndex == 1)
{
NSLog(#"Second Segment (Stations) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.frame.size.width/3;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
else if(segmentedControl.selectedSegmentIndex == 2)
{
NSLog(#"Third Segment (Events) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.view.bounds.size.width - self.segmentedControl.frame.size.width/3;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
}

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

UICollectionViewCell shadow color

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;
}

Resources