center returns the center point for rectAtZeroOrigin
Changing:
with(width:) returns a new size with a new width
with(height:) returns a new size with a new height
adding(width:height) returns a new size by adding to the width or height
adding(_:) returns a new size by adding another size
adding(_:) returns a new size by adding the insets
Subtracting
subtracting(width:height:) subtracts from this size
subtracting(_:) subtracts another size from this size
insetted(by:) insets the size by given insets
Stacking
verticallyStacked(with: spacing) returns the size that is needed to stack this with other
horizontallyStacked(with: spacing) returns the size that is needed to stack this with other
To Points/Pixels
roundedToNearestPixel() rounds to the nearest pixel
ceiledToNearestPixel() ceils to the nearest pixel
flooredToNearestPixel() floors to the nearest pixel
roundedToFullPoints() rounds to full (integer) points
ceiledToFullPoints() ceils to full (integer) points
flooredToFullPoints() floors to full (integer) points
Aspect Fitting
sizeThatFitsSize(_:) returns a size thats in the other size, while maintaining aspect ratio
aspectFill(for:) returns the size that aspect fills in the given other size
aspectFit(for:) returns the size that aspect fits in the given other size
aspectScale(for:) returns the size that aspect scales in the given size
Other
isEmpty true if width or height are <= 0
greatestFiniteMagnitude both width and height are set to greatestFiniteMagnitude, useful for UIView.sizeThatFits()
CGRect
Derived Points
center
topLeft
topRight
bottomLeft
bottomRight
midX
midY
topMiddle
bottomMiddle
midLeft
midRight
Changing
with(origin:) returns a new rect with a new origin
with(size:) returns a new rect with a new size
with(x:) returns a new rect with a new x origin
with(y:) returns a new rect with a new y origin
with(height:) returns a new rect with a new height
with(width:) returns a new rect with a new width
Offsetted
offsetted(by:) returns a new rect offsetted by a point/insets
offsetted(x:y:) returns a new rect offsetted by x and y
Insettted
insetted(top:left:bottom:right) returns a new rect insetted by the given values
To Points
roundedToNearestPixel returns a new rect with the corners rounded to the nearest pixels
ceiledToNearestPixel returns a new rect with the min coordinates floored, the max coordinates ceiled to the nearest pixel
Fitting
rectThatFitsInRect(_:) returns the rect that fits in this rect, retaining aspect ratio
UIView
When setting the center and bounds of a UIView, one must take special care that the view is actually aligned on pixel boundaries. If not, the view
will be slightly blurry, because the pixels of the grid do not align with the pixel grid of the device.
safeCenter and safeSize automatically do this for you: they make sure that the untransformed frame of the view will be pixel aligned.
Using UIView.frame compensates for the current transform of the view: it literally returns the actual position. More often than not, one wants
to set the frame irregardless of the transform, for example, when doing a scale animation. A way to do this is to set the center and bounds.
safeFrame wraps this by calculating the safeCenter and safeSize for you and setting it correctly, ignoring any transforms.
Euclidian Geometry Helpers
There are also a bunch of helpers for dealing with simple euclidian geometry:
Slope
Line
LineSegment
Circle
CircleArc
Slope
A slope models the slope of a line. Three cases:
zero: the slope of a strict horizontal line
infinity: the slope of a strict vertical line
any other value: the slope of any other line
Creating:
init(rawValue:) creates a slope with a given raw value as slope
.horizontal the horizontal slope
.vertical the vertical slope
init(from:to:) creates a slope from the slope of the line between two points
Methods:
isHorizontal
isVertical
perpendicular the slope perpendicular to this
isAmostEqual(to: tolerance:)
Line
A line goes thru a point with a specific slope and has no start and end point: it goes on forever.
Creation
init(point:slope:) creates a line that goes thru a point with a specific slope
init(verticalLineAtX:) creates a vertical line that goes thru the x coordinate
init(horizontalLineAtY:) creates a horizontal line that goes thru the y coordinate
init(yIsXTimes:plus:) creates a line from the formula y = x * slope + b
init(from:to:) creates a line that goes thru the two given points
init(tangentFromPointOnCircle:center:) create the line that is tangent for the point on the circle with the given center
Methods
isHorizontal
isVertical
perpendicular(at:tolerance:) creates the line that is perpendicular to this line in the given point, if the given point is on this line, otherwise nil.
Getting positions/values
yValue(forX:) gets the value of y for the given x, if it exists
point(forX:) get the point for the given x, if it exists
xValue(forY:) gets the value of x for the given y, if it exists
point(forY:) gets the point foe the given y, if it exists
Other
contains(other:tolerance:) checks if this line contains the given point
isAlmostEqual(to:tolerance:) check if this line is equal to another line
intersection(with:tolerance:) gets the intersection result from this line to another line, which could be: sameLine, parallel or intersect(at:)
intersectionPoint(with:tolerance:) returns the intersection point of this line with another line, if there’s only one unique intersection point, otherwise nil.
LineSegment
A line segment is a segment of a line between two points.
Creation
init(start) creates a line segment between start and end.
Methods
line gets the line for this segment
slope gets the slope of this segment
isAlmostEqual(to:tolerance:) checks if this line segment is equal to another one
contains(point:tolerance:) checks if the given point is contained by the line segment
Circle
It’s a circle :)
Creation
init(center:radius:) creates a circle with a given center and radius
Methods
isOnCircle(point:tolerance:) check if the given point is on the circle
isInsideCircle(point:tolerance:) checks if the given point is inside the circle
angle(for:tolerance:) returns the angle (in radians) for a point on the circle
point(for:tolerance:) returns the point for a given angle (in radians)
tangent(at:tolerance:) returns the tangent line for a point on the circle
tangent(for:tolerance:) returns the tangent line for a point at the given angle (in radians)
isAlmostEqual(to:tolerance:) checks if this circle is the same as another circle
CircleArc
An arc of a circle. An arc start at a point on a circle and ends at a point on a circle and can go clockwise or counter clockwise.
Creation
init(circle:startPoint:endPoint:clockwise:tolerance:) creates an arc on the circle from start to end point
init(circle:startAngle:endAngle:clockwise:) creates an arc on the circle from start to end angle
init(center:startPoint:endPoint:clockwise:tolerance:) creates an arc on the circle with the given center going thru startPoint and endPoint.
init(center:startPoint:endAngle:clockwise:tolerance:) creates an arc on the circle with the given start point and end angle
Methods
contains(angle:tolerance:) checks if the given angle is contained by the arc
contains(point:tolerance:) checks if the given point on the circle is contained by the arc
isAlmostEqual(to: tolerance:) checks if this arc is equal to another arc
clockwise returns this arc, but in clock wise direction
counterClockwise returns this arc, but in counter clock wise direction
GeometryHelpers
iOS CGSize, CGPoint, CGRect, CGFloat helpers
CGFloat
Helpers such as
roundedToNearestPixelto round a float to the nearest pixel, instead of point. Useful when aligning on pixel boundaries.hairLineHeightthe height of 1 pixel on the screenroundedToNearestPixelceiledToNearestPixelflooredToNearestPixelCGPoint
Helpers such as
with(x:),with(y:)to quickly change a component.Changing
with(x:)new point with a given xwith(y:)new point with a given yOffset
offsetted(by:)offsetted by another pointoffsetted(x:y:)offsetted by some x and yoffsetted(by:)offsetted by insetsreverseOffsetted(by:)undoes the offsetting by another point/insetsFlipping & Mirroring
mirroredreturns a point mirrored alongside the y-axisflippedreturns a point flipped alongside the x-axisTo Pixel/Point
To Points/Pixels
roundedToNearestPixelrounds to the nearest pixelceiledToNearestPixelceils to the nearest pixelflooredToNearestPixelfloors to the nearest pixelroundedToFullPointsrounds to full (integer) pointsceiledToFullPointsceils to full (integer) pointsflooredToFullPointsfloors to full (integer) pointsOther:
slope(to:)returns the slope of the line from this point to another pointCGSize
min(_:)returns the minimum dimensions of self and another sizemax(_:)returns the maximum dimensions self and another sizeConverting to Rects
rectAtZeroOriginreturnsCGRect(origin: .zero, size: self)centerreturns the center point forrectAtZeroOriginChanging:
with(width:)returns a new size with a new widthwith(height:)returns a new size with a new heightadding(width:height)returns a new size by adding to the width or heightadding(_:)returns a new size by adding another sizeadding(_:)returns a new size by adding the insetsSubtracting
subtracting(width:height:)subtracts from this sizesubtracting(_:)subtracts another size from this sizeinsetted(by:)insets the size by given insetsStacking
verticallyStacked(with: spacing)returns the size that is needed to stack this with otherhorizontallyStacked(with: spacing)returns the size that is needed to stack this with otherTo Points/Pixels
roundedToNearestPixel()rounds to the nearest pixelceiledToNearestPixel()ceils to the nearest pixelflooredToNearestPixel()floors to the nearest pixelroundedToFullPoints()rounds to full (integer) pointsceiledToFullPoints()ceils to full (integer) pointsflooredToFullPoints()floors to full (integer) pointsAspect Fitting
sizeThatFitsSize(_:)returns a size thats in the other size, while maintaining aspect ratioaspectFill(for:)returns the size that aspect fills in the given other sizeaspectFit(for:)returns the size that aspect fits in the given other sizeaspectScale(for:)returns the size that aspect scales in the given sizeOther
isEmptytrue if width or height are <= 0greatestFiniteMagnitudeboth width and height are set togreatestFiniteMagnitude, useful forUIView.sizeThatFits()CGRect
Derived Points
centertopLefttopRightbottomLeftbottomRightmidXmidYtopMiddlebottomMiddlemidLeftmidRightChanging
with(origin:)returns a new rect with a new originwith(size:)returns a new rect with a new sizewith(x:)returns a new rect with a new x originwith(y:)returns a new rect with a new y originwith(height:)returns a new rect with a new heightwith(width:)returns a new rect with a new widthOffsetted
offsetted(by:)returns a new rect offsetted by a point/insetsoffsetted(x:y:)returns a new rect offsetted by x and yInsettted
insetted(top:left:bottom:right)returns a new rect insetted by the given valuesTo Points
roundedToNearestPixelreturns a new rect with the corners rounded to the nearest pixelsceiledToNearestPixelreturns a new rect with the min coordinates floored, the max coordinates ceiled to the nearest pixelFitting
rectThatFitsInRect(_:)returns the rect that fits in this rect, retaining aspect ratioUIView
When setting the
centerandboundsof aUIView, one must take special care that the view is actually aligned on pixel boundaries. If not, the view will be slightly blurry, because the pixels of the grid do not align with the pixel grid of the device.safeCenterandsafeSizeautomatically do this for you: they make sure that the untransformed frame of the view will be pixel aligned.Using
UIView.framecompensates for the currenttransformof the view: it literally returns the actual position. More often than not, one wants to set the frame irregardless of thetransform, for example, when doing a scale animation. A way to do this is to set thecenterandbounds.safeFramewraps this by calculating thesafeCenterandsafeSizefor you and setting it correctly, ignoring any transforms.Euclidian Geometry Helpers
There are also a bunch of helpers for dealing with simple euclidian geometry:
SlopeLineLineSegmentCircleCircleArcSlope
A slope models the slope of a line. Three cases:
Creating:
init(rawValue:)creates a slope with a given raw value as slope.horizontalthe horizontal slope.verticalthe vertical slopeinit(from:to:)creates a slope from the slope of the line between two pointsMethods:
isHorizontalisVerticalperpendicularthe slope perpendicular to thisisAmostEqual(to: tolerance:)Line
A line goes thru a point with a specific slope and has no start and end point: it goes on forever.
Creation
init(point:slope:)creates a line that goes thru a point with a specific slopeinit(verticalLineAtX:)creates a vertical line that goes thru the x coordinateinit(horizontalLineAtY:)creates a horizontal line that goes thru the y coordinateinit(yIsXTimes:plus:)creates a line from the formulay = x * slope + binit(from:to:)creates a line that goes thru the two given pointsinit(tangentFromPointOnCircle:center:)create the line that is tangent for the point on the circle with the given centerMethods
isHorizontalisVerticalperpendicular(at:tolerance:)creates the line that is perpendicular to this line in the given point, if the given point is on this line, otherwise nil.Getting positions/values
yValue(forX:)gets the value of y for the given x, if it existspoint(forX:)get the point for the given x, if it existsxValue(forY:)gets the value of x for the given y, if it existspoint(forY:)gets the point foe the given y, if it existsOther
contains(other:tolerance:)checks if this line contains the given pointisAlmostEqual(to:tolerance:)check if this line is equal to another lineintersection(with:tolerance:)gets the intersection result from this line to another line, which could be:sameLine,parallelorintersect(at:)intersectionPoint(with:tolerance:)returns the intersection point of this line with another line, if there’s only one unique intersection point, otherwise nil.LineSegment
A line segment is a segment of a line between two points.
Creation
init(start
)creates a line segment between start and end.Methods
linegets the line for this segmentslopegets the slope of this segmentisAlmostEqual(to:tolerance:)checks if this line segment is equal to another onecontains(point:tolerance:)checks if the given point is contained by the line segmentCircle
It’s a circle :)
Creation
init(center:radius:)creates a circle with a given center and radiusMethods
isOnCircle(point:tolerance:)check if the given point is on the circleisInsideCircle(point:tolerance:)checks if the given point is inside the circleangle(for:tolerance:)returns the angle (in radians) for a point on the circlepoint(for:tolerance:)returns the point for a given angle (in radians)tangent(at:tolerance:) returns the tangent line for a point on the circletangent(for:tolerance:)returns the tangent line for a point at the given angle (in radians)isAlmostEqual(to:tolerance:)checks if this circle is the same as another circleCircleArc
An arc of a circle. An arc start at a point on a circle and ends at a point on a circle and can go clockwise or counter clockwise.
Creation
init(circle:startPoint:endPoint:clockwise:tolerance:)creates an arc on the circle from start to end pointinit(circle:startAngle:endAngle:clockwise:)creates an arc on the circle from start to end angleinit(center:startPoint:endPoint:clockwise:tolerance:)creates an arc on the circle with the given center going thru startPoint and endPoint.init(center:startPoint:endAngle:clockwise:tolerance:)creates an arc on the circle with the given start point and end angleMethods
contains(angle:tolerance:)checks if the given angle is contained by the arccontains(point:tolerance:)checks if the given point on the circle is contained by the arcisAlmostEqual(to: tolerance:)checks if this arc is equal to another arcclockwisereturns this arc, but in clock wise directioncounterClockwisereturns this arc, but in counter clock wise direction