Does anybody know how to create an UITableView with a curved frame, like MacOS downloads (in Dock panel) on iOS?
I tried to use for this the UIBezierPath class, but unfortunally I didn't succeed. For example I did this:
_tableView = [[TVCurveTableView alloc] initWithFrame:CGRectMake(10, self.view.frame.size.height - 130, 70, 160)];
UIBezierPath *bezierPath = [[UIBezierPath alloc]init];
[bezierPath moveToPoint:CGPointMake(10, self.view.frame.size.height - 10)];
[bezierPath addLineToPoint:CGPointMake(40, (self.view.frame.size.height-10) - 160)];
[bezierPath addLineToPoint:CGPointMake(110, (self.view.frame.size.height-10) - 160)];
[bezierPath addLineToPoint:CGPointMake(80, (self.view.frame.size.height-10))];
[bezierPath addLineToPoint:CGPointMake(10, (self.view.frame.size.height-10))];
[bezierPath closePath];
bezierPath.lineWidth = 2;
CAShapeLayer *shapeView = [[CAShapeLayer alloc] init];
[shapeView setPath:bezierPath.CGPath];
shapeView.strokeColor = [UIColor redColor].CGColor;
[_tableView.layer addSublayer:shapeView];
Maybe you have some ideas?
My COBezierTableView does something similar though not with the tilting of the cells. That would be a nice thing to have as a option though, so maybe I´ll look into it. Fell tree also to deliver a pullrequest yourself if you find a sollution. ;-)
https://github.com/knutigro/COBezierTableView
Related
This question already has answers here:
How to set layer cornerRadius for only bottom-left, bottom-right, and top-left corner?
(13 answers)
How to set cornerRadius for only top-left and top-right corner of a UIView?
(31 answers)
Closed 4 years ago.
I have a UIView i need to give an arc only to the bottom left and bottom right corners of UIView like an arc, eg-like old space bar key on keyboard?
If you want to do this:
You can use this code:
NSInteger marginCurve = 30;
UIView *example1 = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 2)];
[example1 setBackgroundColor: [UIColor clearColor]];
UIBezierPath *curve1 = [UIBezierPath bezierPath];
[curve1 moveToPoint: CGPointMake(0, 0)];
[curve1 addLineToPoint: CGPointMake(example1.frame.size.width, 0)];
[curve1 addLineToPoint: CGPointMake(example1.frame.size.width, example1.frame.size.height - marginCurve)];
[curve1 addCurveToPoint: CGPointMake(0, example1.frame.size.height - marginCurve)
controlPoint1: CGPointMake(example1.frame.size.width / 2, example1.frame.size.height)
controlPoint2: CGPointMake(example1.frame.size.width / 2, example1.frame.size.height)];
[curve1 closePath];
CAShapeLayer *ex1Layer = [CAShapeLayer layer];
[ex1Layer setFrame: example1.bounds];
[ex1Layer setFillColor: [UIColor brownColor].CGColor];
[ex1Layer setPath: curve1.CGPath];
[example1.layer addSublayer: ex1Layer];
[self.view addSubview: example1];
I hope it helps you :)
Its a bit unclear what you mean by 'eg-like old space bar key on keyboard', but it sounds like you need to make a custom drawn UIView.
You do that by:
Making a subclass of UIView and override -(void)drawRect:(CGRect)rect
In here you can make a custom drawing most likely using UIBezierPath
A BezerPath can represent a large number of shapes and forms.
Depending on what you want to draw it will look something like:
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIBezierPath * path in self.paths) {
CGContextAddPath(ctx, path.CGPath);
CGContextSetStrokeColorWithColor(ctx,self.color.CGColor);
CGContextStrokePath(ctx);
}
See this excellent tutorial on UIBezierPath
i want to obtain the progress bar like in the image below:
Striped loading progress bar with triangle at the end
Here is what i've done so far, with the help of the project from github https://github.com/iluuu1994/ITProgressBar-iOS, so here is what i attempted:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(42, self.frame.size.height-10), NO, 0.f);
UIColor* color = [UIColor colorWithRed:251.0f/255.0f green:235.0f/255.0f blue:77.0f/255.0f alpha:1.0f];
UIBezierPath *bezierPath = [UIBezierPath new];
[bezierPath moveToPoint:CGPointMake(0.0, 0.0)];
[bezierPath addLineToPoint:CGPointMake(23, 0)];
[bezierPath addLineToPoint:CGPointMake(42, 29)];
[bezierPath addLineToPoint:CGPointMake(23, 70)];
[bezierPath addLineToPoint:CGPointMake(0, 70)];
[bezierPath addLineToPoint:CGPointMake(20, 29)];
[bezierPath addLineToPoint:CGPointMake(0, 0)];
[bezierPath closePath];
[color setFill];
[bezierPath fill];
}];
}
I tried to override the drawRect method from UIView but nothing seems to work, so i fought to apply a mask to the layer I'am using.
i have a UIView with layout constraint (width:400, height:180) and i want to add a bezier inside the view.
my bezier is this:
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
// origin, height | left border
[bezierPath moveToPoint: CGPointMake(0, 20)];
// origin, height | left border
[bezierPath addLineToPoint: CGPointMake(0, _donationView.frame.size.height)];
// height, width | bottom border
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width , _donationView.frame.size.height)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width, 20)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 20, 20)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 30, 15)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 40, 20)];
[bezierPath addLineToPoint: CGPointMake(0, 20)];
[bezierPath closePath];
[UIColor.grayColor setFill];
[bezierPath fill];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
after creating bezier i pass to:
CAShapeLayer *shapeView = [[CAShapeLayer alloc] initWithLayer:_donationView.layer];
[shapeView setPath:bezierPath.CGPath];
_donationView.layer.mask = shapeView;
but the bezier goes to this CGRect(0, 0, 240, 128);
how can i have a CGRect of (0,0,400, 180)?
thanks guys
The problem is that you're doing this too soon, before donationView has attained its final size. Thus, when you read off its frame.size, you are getting the wrong result. You need to postpone the addition of the mask until after layout has taken place.
You can also run into further issues if donationView is ever resized later. It is quite annoying that a mask layer (or any layer) doesn't get to participate in autolayout. So if donationView is resized, you will have to remove this mask and create a new mask with the correct size and add it again.
I am trying to find the best way to implement an rounded rectangle (e.g. looling like the iphone icons). My search suggested using UIBezierPath.
In order to test that class I made a new xcode template (single view application) and basically just added the following lines in ViewController's viewDidLoad:
UIBezierPath* path = [UIBezierPath
bezierPathWithRoundedRect: CGRectMake(10, 10, 120, 120)
cornerRadius: 5];
[[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0] setFill];
[path stroke];
[path fill];
Now I get several "...invalid context 0x0 error...". I assume that I have to set a context first?! But how do I do this or if not fix those errors otherwise?
My search on that error came up with a few posts. Unfortunaltely all of them seemed to have rather complex coding associated. I'm pretty sure however that I have just a very basic misunderstanding here.
Thank you!
you can use this and assign that in layer of your view
UIBezierPath *maskpath=[UIBezierPath bezierPathWithRoundedRect:view1.bounds
byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight
cornerRadii:CGSizeMake(10.0,10.0)];
CAShapeLayer *maskLayer=[CAShapeLayer layer];
maskLayer.frame=view1.bounds;
maskLayer.path=maskpath.CGPath;
[view1.layer addSublayer:maskLayer];
in case it is helpful for someone else: on basis of the code provided by johnykumar and another post on a similar topic:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
CGRect frame = CGRectMake(50.0, 50.0, 150.0, 150.0);
CGFloat radius = 20.0;
UIView *frontView = [[UIView alloc] initWithFrame:frame];
frontView.backgroundColor = [UIColor redColor];
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:frontView.bounds
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(radius, radius)].CGPath;
frontView.layer.mask = maskLayer;
[self.view addSubview:frontView];
}
I am trying to use UIbezierPaths for the first time and I am having no success in displaying it in the view. I am using a very old version of xcode (3.2.6).
-(void)drawshape:(CGRect)Rect {
UIBezierPath *cloudpath = [UIBezierPath bezierPath];
[cloudpath moveToPoint:CGPointMake(100.0, 100.0)];
[cloudpath addLineToPoint:CGPointMake(200, 200)];
[cloudpath addLineToPoint:CGPointMake(200, 300)];
[cloudpath addLineToPoint:CGPointMake(250, 330)];
[cloudpath addLineToPoint:CGPointMake(20, 400)];
[cloudpath closePath];
cloudpath.lineWidth = 2;
[[UIColor blueColor]setStroke];
[cloudpath stroke];
}
I have also Imported QuartzCore. I have only added -(void)drawshape in viewcontroller.h
When I build, i have no errors.Any help is massively welcomed
You will need to initiate the drawing from overriding drawRect: in a custom UIView and not in your view controller.