having trouble drawing a rectangle to the screen ios - ios

I am following a video tutorial from pluralsight that draws a red rectangle to the screen. I have a subclass of UIView called PSViewDemo that has the following code in the .m file:
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, CGRectMake(40, 400,100,200));
// Drawing code
}
I call it in the Viewdidload of the viewcontroller for the only view in the application (until the code adds the subview).
- (void)viewDidLoad
{
[super viewDidLoad];
PSViewDemo *dv = [[PSViewDemo alloc] initWithFrame:CGRectMake( 0, 0, 320, 480)];
[self.view addSubview:dv];
// Do any additional setup after loading the view, typically from a nib.
}
The whole thing compiles and runs without error but there is no red rectangle on the screen.
What am I missing? I am pretty sure I am following the tutorial exactly so maybe something has changed in Cocoa since the tutorial was made? I'm using xCode 5.

Change
CGContextSetFillColor(context, [UIColor redColor].CGColor);
To
CGContextSetFillColor(context, CGColorGetComponents([[UIColor redColor] CGColor]));

Related

[iOS][ReactNative v0.19.0] Custom view has an unexpected black background

I have a custom view drawing colored path, worked well before React Native 0.19
But on React Native 0.19, it seems like there is a default black background, which prevent me from using translucent colors.
It looks like this on React Native 0.19:
If I draw nothing or some translucent color on the entire rect, you'll see the black layer
- (void)drawRect:(CGRect)rect
{
[[UIColor colorWithWhite:0 alpha:0] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 20, 20)];
[[UIColor redColor] setFill];
[path fill];
}
please help me fix this problem.
React Native v0.19.0
running on iPhone 6s Plus (9.2) simulator
It's common when you override -drawRect to perform custom drawing, you need to set its opaque to NO or set its background colour manually in -initWithFrame:
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setOpaque:NO];
// or [self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
Btw, it's not black though we see it in black. It's just because there's no colour offered there to be shown appropriately, cause you override -drawRect, you take charge of the drawing related logic, but you did't take care of this area as expected.

iOS How can I draw small circle limit in the big circle in movement

I want to achieve the effect shown in this github project, but I don't want to use SpriteKit to achieve this.
So I try to draw the big circle in the CircleViiew.m about the CGContextRef in Objective-C.
#import "CircleView.h"
#import <QuartzCore/QuartzCore.h>
#define CIRCLE_RADIUS 80
#implementation CircleView
-(id) initWithFrame:(CGRect)frame andCircleRadius:(int) radius
{
self = [super initWithFrame:frame];
if(self)
{
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// set rect background color
CGRect drawRect = CGRectMake(rect.origin.x, rect.origin.y,rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, 100.0f/255.0f, 100.0f/255.0f, 100.0f/255.0f, 1.0f);
CGContextFillRect(context, drawRect);
// set line border number
CGContextSetRGBStrokeColor(context,0.6,1,0.6,1.0);
CGContextSetLineWidth(context, 2.0);
CGContextAddArc(context, 82, 82, CIRCLE_RADIUS, 0, 2*M_PI, 0);
CGContextDrawPath(context, kCGPathStroke);
// fill color
UIColor *fillCircleColor = [UIColor colorWithRed:1.000 green:0.800 blue:0.000 alpha:1.000];
CGContextSetFillColorWithColor(context, fillCircleColor.CGColor);
CGContextAddArc(context, 82, 82, CIRCLE_RADIUS, 0, 2*M_PI, 0);
CGContextDrawPath(context, kCGPathFill);
CGContextDrawPath(context, kCGPathFillStroke);
}
#end
Then in the ViewController using the circle.
CircleView *circle = [[CircleView alloc] initWithFrame:CGRectMake(20, 20, 164, 164)];
[self.view addSubview:circle];
But I don't know how to add the small circle overlay the big circle, and the small have to limit on the big circle when we movement the small circle.
Is create small circle object using CircleView on the viewDidload to overlay BigCircle? Or the small circle have to draw in the CircleView class?
I am using auto layout to create the effect. I don't know if I use initwithFrame to make, have generate problem after.
Can anyone give me some direction?
Draw the small circle as a separate view, lying in front of (on top of) the big circle. It can be a UIImageView, for example.
Give the small circle a UIPanGestureRecognizer to make it draggable.
In the gesture recognizer handler, move the view to follow the user's gesture, except that you don't move the view if it would move further than a certain distance from the big circle's center.

iOS - CGContextStrokePath/CGContextDrawPath remove black background color

I'm trying to draw a straight dashed line. I've gotten it so it draws the dashes, but this black background color remains. I've seem many answers to other questions, but none of them worked.
Apple's documentation seems to point to the fill color and using either CGContextFillPath or CGContextDrawPath, but neither of those work and the background of the dashed line is still black.
- (void)drawRect:(CGRect)rect {
CGContextRef contextRef = UIGraphicsGetCurrentContext();
GLFloat lines[] = {self.frame.size.width, self.frame.size.width*2};
CGFloat grey[4] = {0.6f, 0.6f, 0.6f, 1.0f};
CGContextSetStrokeColor(contextRef, grey);
CGContextSetFillColorWithColor(contextRef, [[UIColor clearColor] CGColor]);
CGContextSetLineDash(contextRef, 0, lines, 2);
CGContextSetLineWidth(contextRef, self.frame.size.width);
CGContextBeginPath(contextRef);
CGContextMoveToPoint(contextRef, 0, 0);
CGContextAddLineToPoint(contextRef, 0, self.frame.size.height);
CGContextDrawPath(contextRef, kCGPathFillStroke);
}
When manually adding this view to your view hierarchy, you just have to make sure you're setting the background color. For example, if you're initializing your view with initWithFrame, then set the background color in that method:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
Or, alternatively, when adding the view, set the background color there:
CustomView *customView = [[CustomView alloc] initWithFrame:frame];
customView.backgroundColor = [UIColor clearColor];
[self.view addSubview:customView];

UIBezierPath simple rectangle

I just want to draw a simple rectangle to a view using the following function:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.drawTextBouble) {
[[UIColor blueColor] setFill];
UIBezierPath *aPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40, 0, 230, 120) cornerRadius:12.0];
[aPath fill];
}
}
The code above fills the view with plain black background, outside the rectangle is not transparent. How can I fix this?
Edit:
The solution below is working, but this is working also:
[self setOpaque:NO];
You drawing code is OK. If you want the custom drawn view to have transparent background, you just need to set
self.backgroundColor = [UIColor clearColor];
in view's - (id)initWithFrame:(CGRect)frame
Edit: Just a little note regarding calling [super drawRect:rect]. UIView docs says:
If you subclass UIView directly, your implementation of this method does not need to call super. However, if you are subclassing a different view class, you should call super at some point in your implementation.

How do you darken UIScrollView's overflow?

Suppose you wanna implement the same functionality iOS's camera 'Zoom & Crop' has... in which you can scroll and crop an image.
Any section of the picture that exceeds the size of the crop area gets grayed out.
I'm trying to replicate exactly that. Provided that the flag 'clipToBounds' is set to NO, you can get the whole subview to get displayed.
However, i'm finding it a bit hard to gray out the UIScrollView's subviews overflow.
How would you implement that?.
Thanks in advance!
You can do this by creating a subclass of UIView that is semi-transparent in the overflow region and transparent in the "crop" region and placing it over your UIScrollView and extending it out to cover the overflow.
The main methods you need to implement are initWithFrame:
#define kIDZAlphaOverlayDefaultAlpha 0.75
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
mAlpha = kIDZAlphaOverlayDefaultAlpha;
self.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:mAlpha];
self.userInteractionEnabled = NO;
}
return self;
}
Don't miss out the userInteractionEnabled = NO otherwise the scroll view will not sees events.
and drawRect
- (void)drawRect:(CGRect)rect
{
CGRect apertureRect = /* your crop rect */;
CGContextRef context = UIGraphicsGetCurrentContext();
/* draw the transparent rect */
CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.0);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextFillRect(context, apertureRect);
/* draw a white border */
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextStrokeRect(context, apertureRect);
}
The important point here is the kCGBlendModeCopy this allows us to draw (or cut) a transparent rectangle in a semi-transparent background.
If you want to can make the transparent rectangle a rounded rectangle, and include a preview of the cropped image and end up with something like the screen below:
Sorry I can't share all the code for the screen shot. It's from a client project :-(
I've solved this issue by...:
Adding a new helper class, 'ApertureOverlay' (subclass of UIView), with the following code:
(void)drawRect:(CGRect)rect
{
if(CGRectEqualToRect(_apertureRect, CGRectZero) == NO)
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context, false);
CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f);
CGContextFillRect(context, _apertureRect);
CGContextSetShouldAntialias(context, true);
}
}
ApertureOverlay has a background with the alpha byte set to 50%.
[self setBackgroundColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.5f]];
So far... al we've got is a view with transparent background, and a white rectangle (drawn with _apertureRect position + size).
After implementing this class, i've set up the 'mask' attribute of the ScrollView, which contains the image inside.
[[self layer] setMask:[_apertureOverlayView layer]];
That's it!. If you update the ApertureOverlay's '_apertureRect' attribute, you'll need to call 'setNeedsDisplay', so it gets redrawn.
One more thing. By setting the antialias to false (ApertureOverlay)... things work pretty smooth.

Resources