Is it possible to set line height less than 1 in Swift? - swift

I am trying to make the line space a little less than the default for a small window.
I have code similar to this question: How to Increase Line spacing in UILabel in Swift
let title = "This is text that will be long enough to form two lines"
let styles = NSMutableParagraphStyle()
styles.lineSpacing = 0.1
let attribs = [
NSAttributedString.Key.paragraphStyle:styles
]
let attrString:NSAttributedString = NSAttributedString.init(string: title, attributes: attribs)
introText.attributedStringValue = attrString
While changing lineSpacing to 10 makes a noticeable difference, I can't see a difference if I make it less than 1.
Here is what 0.1 looks like:

Line spacing is measured in points, not lines. There's basically no such thing as a fraction of a point (for drawing purposes; I am simplifying, since retina screens do exist). Zero is the minimum, and when you say 0.1, you are there; you can't reduce the leading any further.

Keep in mind the relationship of points to pixels. For most recent devices, a point represents two or three pixels. I have set a UIView with a height of 0.5, used as a divider, which is about 1 pixel on many devices, and been able to see the difference. A height of 0.1 is probably rounded off to nothing, though.

Related

Math doesn't work for the size and position of Game Pieces WRT the size of their container "room"

The positions and sizes of my Game Pieces, as set by CGPoint(..) and CGRect(..), don’t make arithmetic sense to me when looked at with respect to the width and height of the surrounding container of all Game Pieces?
Let me illustrate with just one specific example –
I call the surrounding container = “room”.
One of many specific Game Pieces = “rock”.
Here’s the math
roomWidth = Double(UIScreen.main.bounds.width)
roomHeight = Double(UIScreen.main.bounds.height)
While in Portrait mode:
roomWidth = 744.0
roomHeight = 1133.0
When rotated to Landscape mode:
roomWidth = 1133.0,
roomHeight = 744.0
So far so good .. here’s the problem:
When I look at my .sks file, the width of the “rock” and its adjacent game pieces far exceeds the roomWidth; for example,
Widths of rock + paddle + tree = 507 + 768 + 998 which obviously exceeds the room’s width for either Portrait or Landscape mode – and this math doesn’t even address the separation between Game Pieces.
The final math “craziness” looks at the swift xPos values for each Game Piece as specified in my .sks file:
Room: xPos = 40,
Rock: xPos = -390,
Paddle: xPos = -259,
Tree: xPos = 224
I cannot grasp the two high negative numbers .. to me, that means the Rock and the Paddle shouldn’t even be visible .. seriously off-screen.
One significant addition = I did set the Autoresizing Mask to center horizontally and vertically
I need a serious infusion of “smarts” here.
The default anchorPoint of an sks file (SpriteKit Scene file) is (0.5, 0.5). So the origin (0, 0) of the scene is drawn at the center of the SKView. You can change the anchor point in the Attributes inspector when editing the sks file. The default means that negative coordinates not too far from the origin will be visible in the SKView.
The scene also has a scaleMode property which determines how the scene is scaled if its size doesn't match the SKView's size. The default is .fill, which means the view scales the scene's axes independently so the scene's size exactly fills the view.

how to make horizontal padding in iOS danielgindi charts

I'm using the ios-charts library and I would like to add some horizontal padding to my line charts so that the line does not start immediately at the border of the graph.
This is my current chart:
but I would like the blue line to have some padding as shown below. The rest should remain as it is. The reference gray lines should still take the entire width as they currently do.
I found it. This "padding" is actually ruled by the chart.xAxis.axisMinimum and chart.xAxis.axisMaximum. Those values are automatically set to the data min x and max x.
So if I want a left padding I just have to set a chart.xAxis.axisMinimum
In my case, I want around 10% of the x values to be padded, so I calculate it as
// dates is an array of Date representing my x values
if let maxX = dates
.map(\.timeIntervalSince1970)
.max(),
let minX = dates
.map(\.timeIntervalSince1970)
.min() {
let spanX = maxX - minX
let padding = spanX * 0.1
let axisMinimum = minX - padding
// set the left padding
chart.xAxis.axisMinimum = axisMinimum
}

Swift CAShapeLayer gets partially transparent at 1pt or lower

I've been trying to get a solid color when I draw a 0.5pt width line but it gets opaque when the value is 1.0 or less (see picture).
This is the code (Swift 4)
func DrawLine(from:CGPoint, to:CGPoint) {
let path = UIBezierPath()
path.move(to: from)
path.addLine(to: to)
let lineLayer = CAShapeLayer()
lineLayer.path = path.cgPath
lineLayer.lineWidth = linesWidth
lineLayer.strokeColor = linesColor.cgColor
lineLayer.isOpaque = false // trying to make it work line
lineLayer.opacity = 1 // trying to make it work line
lineLayer.shadowColor = UIColor.clear.cgColor // trying to make it work line
lineLayer.shadowOffset = .zero // trying to make it work line
lineLayer.shadowOpacity = 0 // trying to make it work line
self.layer.insertSublayer(lineLayer, at: 0)
}
Thanks.
I found an answer at https://www.raywenderlich.com/411-core-graphics-tutorial-part-1-getting-started (All because the anti-aliasing as explained in the first answer by Codo)
If you have oddly sized straight lines, you’ll need to position them
at plus or minus 0.5 points to prevent anti-aliasing
So, if the lineWidth is 1pt or less I add 0.5 points or (1 / scale).
Now the line is crispy
I think when you say opaque you rather mean partially transparent. And I guess we're talking about macOS here, right?
How do you expect a line of less than 1 pixels looks on the screen? A pixel is the smallest unit of the screen. The entire pixel has the same color. It can't be partially red and partially white.
So macOS – as part of the antialiasing – blends the thin line and the background, i.e. it makes the pixels partially transparent before drawing them on the background. The effect is that the line is perceived as thinner even though it is still 1 pixel wide.
If you don't like this effect, do not draw lines of less than 1 pixel. But it's the only way a line looks thinner than 1 pixel.
BTW: Pixel size depends on the resolution. On a retina device, 1 pixel is 0.5 point, on non-retina devices it's 1 point and there are even factors in-between.

Label text truncated after increasing font size

I followed the procedures in this question, and also tried setting individual text object with larger fonts. Here is my sample code:
hf = figure;
set(hf, 'DefaultAxesFontSize', 14)
hx = axes('Parent',hf);
[hx,hp1,hp2] = plotyy(hx, rand(10,1),rand(10,1),rand(10,1),rand(10,1),'scatter');
hlx = xlabel(hx(1), 'Only half of this line show up');
hl1 = ylabel(hx(1), 'Not usually truncated but less border');
hl2 = ylabel(hx(2), 'Only part of this line show up');
ht = title(hx(1), 'Too close to border');
As can be seen in the picture, the labels get truncated by the border of the figure. I have to drag the figure to very large - contrary to desired - in order to reveal all text.
How can I automatically set the text box according to the text font size, so that even for small graphs they don't get cut?
I know I can do it manually by setting Position of the axes but it's kind of manual and guess-and-try. Is there any automatic way to calculate the margins?
One thing that can be done is to calculate increased margin according to new text font size. Assume we know Matlab's default font size is 10, or otherwise get it by get(hf,'DefaultAxesFontSize').
Then get the relative position of the axes by get(hx, 'Position'), which gives four percentage values. First two define left and bottom margin. Since it's for the labels, increasing the font size from 10 to 14 means the text box should grow by 1.4 times. The next two numbers define the size of the axis. Since text boxes on both sides grow by 1.4 times, assuming original size being x, then new size is 1-[(1-x)*1.4] = 1.4x - 0.4.
Suggested workaround:
hf = figure;
set(hf, 'DefaultAxesFontSize', 14)
hx = axes('Parent',hf);
set(hx, 'Position', [1.4 1.4 1.4 1.4].*get(hx, 'Position')+ [0 0 -.4 -.4])
[hx,hp1,hp2] = plotyy(hx, rand(10,1),rand(10,1),rand(10,1),rand(10,1),'scatter');
hlx = xlabel(hx(1), 'Only half of this line show up');
hl1 = ylabel(hx(1), 'Not usually truncated but less border');
hl2 = ylabel(hx(2), 'Only part of this line show up');
ht = title(hx(1), 'Too close to border');
You may replace the manually entered number 1.4 with the ratio between newly assigned (bigger, hopefully) font size and the original size which is 10.

Detect textfield overflowing

I'd like to be able to detect when a UITextfield overflows it bounds.
I want to detect Horizontal overflow (since there is only 1 line).
I was thinking about counting the amount of characters and multiplying that with a default value for the letter width and see if that fits inside the textfield bounds but that wouldn't work due too the letter having different widths.
I am aware of adjustsFontSizeToFitWidth but I want to increase the width of the textfield instead of decreasing the font size.
Here is the code which first calculates the size of the text and then compares it to the label size:
let textSize: CGSize = self.label.text!.sizeWithAttributes([NSFontAttributeName: self.label.font])
let isOverflowing: Bool = textSize.width > self.label.frame.size.width