How to format table cell to have rounded corners? - xcode

I want rounded corners for my Table Cell View. So I just set the background to transparent but this removes the whole background of the cell.
Any idea how to do that using the visual editor?

There are some ways to achieve that:
override drawRect in your custom tableViewCell class. This is drawing by hand, very nasty ;) I'll post an example code below for a rounded corner background.
put an imageView in the background and add a picture with round corners to the cell. (Background is transparent of course). The problem with transparent backgrounds is performance.
example code for a backround with round corners
float radius = 10.0;
CGContextRef context = UIGraphicsGetCurrentContext();
rect = CGRectInset(rect, 1.0f, 1.0f);
CGContextBeginPath(context);
CGContextSetGrayFillColor(context, 0.0, 0.8);
CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect));
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect) + radius, radius, 3 * M_PI / 2, 0, 0);
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect) - radius, radius, 0, M_PI / 2, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius, radius, M_PI / 2, M_PI, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) + radius, radius, M_PI, 3 * M_PI / 2, 0);
CGContextClosePath(context);
CGContextFillPath(context);

Related

How to add labels onto segments of a circle in p5.js?

I’m working on a project with p5.js where I draw a circle, draw arcs (straight red lines) to separate the circle then another arc between each of the red lines (blue lines). The idea looks like the included image below:
What I'm confused about is how to position the labels in the circle drawing so that they're positioned in each segment inside the circle but outside the blue arcs. My question is how do I add text labels to this figure so that it looks like the image below?
Here is the shortened code to produce the first image (circle without the labels) so far:
function setup() {
createCanvas(400, 400);
}
function draw() {
background(255);
let startX = 50;
let startY = 50;
let data = [1, 2, 3, 4];
let width = 80;
let angle = -Math.PI / 2;
let radianPer = Math.PI * 2 / Object.keys(data).length;
noStroke();
fill(255);
ellipse(startX, startY, width, width);
Object.keys(data).forEach(i => {
fill(255);
stroke(255, 0, 0);
arc(startX, startY, width, width, angle, angle + radianPer, PIE);
fill(255);
stroke(0, 0, 255);
arc(startX, startY, width / 2, width / 2, angle, angle + radianPer, PIE);
angle += radianPer;
// add label here
});
}
Edit (02/05/22): updated code to match the screenshot image example.
Displaying a label in the middle of a segment of an arc involves using the angle for the middle of that arc with the sine and cosine functions to find the X and Y coordinates. For more information see the trigonometric functions article on wikipedia.
function setup() {
createCanvas(400, 400);
// Text settings
textAlign(CENTER, CENTER);
}
function draw() {
background(255);
let startX = 50;
let startY = 50;
let data = [1, 2, 3, 4];
let width = 80;
let angle = -Math.PI / 2;
let radianPer = (Math.PI * 2) / Object.keys(data).length;
noStroke();
fill(255);
ellipse(startX, startY, width, width);
Object.keys(data).forEach((i) => {
fill(255);
stroke(255, 0, 0);
arc(startX, startY, width, width, angle, angle + radianPer, PIE);
fill(255);
stroke(0, 0, 255);
arc(startX, startY, width / 2, width / 2, angle, angle + radianPer, PIE);
// add label here
let textAngle = angle + radianPer / 2;
// Use sine and cosine to determine the position for the text
// Since sine is opposite / hypotenuse, taking the sine of the angle and
// multiplying by distance gives us the vertical offset (i.e. the Y
// coordinate).
// Likewise with cosine for the X coordinate
noStroke();
fill(0);
text(
data[i].toString(),
startX + cos(textAngle) * width / 2 * 0.75,
startY + sin(textAngle) * width / 2 * 0.75
);
// Don't update angle until after calculating the angle for the label
angle += radianPer;
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

OpenGL ES 2.0 renders coloured screen without the images

I'm trying to render sprites using OpenGL ES 2.0. However I only get a coloured screen without the sprites. Everything is setup correctly as far as I see. What could be wrong? Here is how I setup the projection and view matrices:
this.position = new Vector2(frustumWidth/2, frustumHeight/2);
for(int i=0;i<16;i++)
{
mtrxProjection[i] = 0.0f;
mtrxView[i] = 0.0f;
mtrxProjectionAndView[i] = 0.0f;
}
Matrix.orthoM(mtrxProjection, 0, position.x - frustumWidth * zoom / 2,
position.x + frustumWidth * zoom / 2,
position.y - frustumHeight * zoom / 2,
position.y + frustumHeight * zoom / 2,
10 , -10 );
Matrix.setLookAtM(mtrxView, 0, position.x, position.y, 0.0f, position.x, position.y, -1.0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0);

How to position a textured quad in screen coordinates?

I am experimenting with different matrices, studying their effect on a textured quad. So far I have implemented Scaling, Rotation, and Translation matrices fairly easily - by using the following method against my position vectors:
enter code here
for(int a=0;a<noOfVertices;a++)
{
myVectorPositions[a] = SlimDX.Vector3.TransformCoordinate(myVectorPositions[a],myPerspectiveMatrix);
}
However, I what I want to do is be able to position my vectors using world-space coordinates, not object-space.
At the moment my position vectors are declared thusly:
enter code here
myVectorPositions[0] = new Vector3(-0.1f, 0.1f, 0.5f);
myVectorPositions[1] = new Vector3(0.1f, 0.1f, 0.5f);
myVectorPositions[2] = new Vector3(-0.1f, -0.1f, 0.5f);
myVectorPositions[3] = new Vector3(0.1f, -0.1f, 0.5f);
On the other hand (and as part of learning about matrices) I have read that I need to apply a matrix to get to screen coordinates. I've been looking through the SlimDX API docs and can't seem to pin down the one I should be using.
In any case, hopefully the above makes sense and what I am trying to achieve is clear. I'm aiming for a simple 1024 x 768 window as my application area, and want to position a my textured quad at 10,10. How do I go about this? Most confused right now.
I am not familiar with slimdx, but in native DirectX, if you want to draw a quad in screen coordinates, you should define the vertex format as Translated, that is you specify the screen coordinates directly instead of using D3D transform engine to transform your vertex. the vertex definition as below
#define SCREEN_SPACE_FVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
and you can define your vertex like this
ScreenVertex Vertices[] =
{
// Triangle 1
{ 150.0f, 150.0f, 0, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 350.0f, 150.0f, 0, 1.0f, 0xff00ff00, },
{ 350.0f, 350.0f, 0, 1.0f, 0xff00ffff, },
// Triangle 2
{ 150.0f, 150.0f, 0, 1.0f, 0xffff0000, },
{ 350.0f, 350.0f, 0, 1.0f, 0xff00ffff, },
{ 150.0f, 350.0f, 0, 1.0f, 0xff00ffff, },
};
By default screen space in 3d systems is from -1 to 1 (where -1,-1 is bottom left corner and 1,1 top right).
To convert those unit to pixel values, you need to convert pixel values into this space. So for example pixel 10,30 on a screen of 1024*768 is:
position.x = 10.0f * (1.0f / 1024.0f); // maps to 0/1
position.x *= 2.0f; //maps to 0/2
position.x -= 1.0f; // Maps to -1/1
Now for y you do
position.y = 30.0f * (1.0f / 768.0f); // maps to 0/1
position.y = 1.0f - position.y; //Inverts y
position.y *= 2.0f; //maps to 0/2
position.y -= 1.0f; // Maps to -1/1
Also if you want to apply transforms to your quads, It is better to send the transformation to the shader (and do the vector transformation in the vertex shader), rather than doing the multiplications on the vertices, since you will not need to update your vertexbuffer every time.

GopenGL align texture coordinates to world, not to face

What I currently have: Generating of texture coordinates given the width and height of a rectanlge along with a scale factor for the texture. this is woking fine:
vertices = new float[] {
0, 0, 0, this.height / (this.texture.height * this.texScaleHeight),
this.width, 0, this.width / (this.texture.width * this.texScaleWidth), height / (this.texture.height * this.texScaleHeight),
this.width, this.height, this.width / (this.texture.width * this.texScaleWidth), 0,
0, this.height, 0, 0 };
What I want to do now, is that some rectangles with different positions (ie. next to each other) have a seamless graduation for the textures. I tried the following but with no good result.
vertices = new float[] {
0, 0, -this.getPosition().x * this.texScaleWidth, this.height / (this.texture.height * this.texScaleHeight) -this.getPosition().y * this.texScaleHeight,
this.width, 0, this.width / (this.texture.width * this.texScaleWidth) -this.getPosition().x * this.texScaleWidth, height / (this.texture.height * this.texScaleHeight)-this.getPosition().y * this.texScaleHeight,
this.width, this.height, this.width / (this.texture.width * this.texScaleWidth) -this.getPosition().x * this.texScaleWidth, -this.getPosition().y * this.texScaleHeight,
0, this.height, -this.getPosition().x * this.texScaleWidth, -this.getPosition().y * this.texScaleHeight };
How can i achieve that textures are "aligned to the world" and not to the rectangle they sit on?
This technique is potentially way too general, but here it goes: You could project the texture coordinates onto the geometry.
The overall workflow is just the same as handling geometry itself, but here, all world points are assigned texture coordinates. Push every point in the geometry through another MVP matrix (representing the projector) and take the (x, y) result for the texture coordinate of this very point (assuming orthographic projection); perspective requires division by w afterwards.
I hope you get the idea. Searching for it, I failed to find a decent description or tutorial. Shadow mapping uses the same technique, but its goal is to determine whether a point is shadowed or not; here, the goal is to find texture coordinates for a general projector.

How can I remove a UIView with rounded corners from its parent view?

I'm creating an iPad app for 3.2 and later. My app has an overlay view which has a semi-transparency that makes everything below it darker. In the middle of this view I am chopping a hole in this semi-transparency to let part of the background filter through unscathed, with this code:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect intersection = CGRectIntersection(hole.frame, rect);
CGContextClearRect(context, intersection);
}
Additionally, the 'hole' view has rounded corners, applied via:
self.layer.cornerRadius = 4.25;
This works great except for one small problem - these rounded corners are not taken into account, so the hole that gets chopped out has square corners instead of rounded. I need to fix this, but I have no idea how. Any ideas, examples, thoughts?
Here's how I ended up getting it to work. This produces a hole with the same frame as the 'hole' UIView, cutting it out from self (UIView). This lets you see whatever is behind the 'hole' unhindered.
- (void)drawRect:(CGRect)rect {
CGFloat radius = self.hole.layer.cornerRadius;
CGRect c = self.hole.frame;
CGContextRef context = UIGraphicsGetCurrentContext();
// this simply draws a path the same shape as the 'hole' view
CGContextMoveToPoint(context, c.origin.x, c.origin.y + radius);
CGContextAddLineToPoint(context, c.origin.x, c.origin.y + c.size.height - radius);
CGContextAddArc(context, c.origin.x + radius, c.origin.y + c.size.height - radius, radius, M_PI_4, M_PI_2, 1);
CGContextAddLineToPoint(context, c.origin.x + c.size.width - radius, c.origin.y + c.size.height);
CGContextAddArc(context, c.origin.x + c.size.width - radius, c.origin.y + c.size.height - radius, radius, M_PI_2, 0.0f, 1);
CGContextAddLineToPoint(context, c.origin.x + c.size.width, c.origin.y + radius);
CGContextAddArc(context, c.origin.x + c.size.width - radius, c.origin.y + radius, radius, 0.0f, -M_PI_2, 1);
CGContextAddLineToPoint(context, c.origin.x + radius, c.origin.y);
CGContextAddArc(context, c.origin.x + radius, c.origin.y + radius, radius, -M_PI_2, M_PI, 1);
// finish
CGContextClosePath(context);
CGContextClip(context); // this is the secret sauce
CGContextClearRect(context, c);
}
What you're trying to do is called masking. You can use Core Graphics to mask the current graphics context. See Apple's documentation on the subject here:
http://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html#//apple_ref/doc/uid/TP30001066-CH212-CJBHDDBE
If you change the cornerRadius property of a layer, you must also set clipsToBounds to YES on the associated view in order for the content to be clipped to the rounded corners.

Resources