SwiftUI large font with minimum scale is not aligned in centre - text

Goal is to show a text the largest possible on the screen in any orientation so the solution I had in mind was to make the font size considerably big but add a minimum scale factor modifier to it such as the following.
struct ContentView: View {
var body: some View {
Text("U")
.font(.system(size: 2000
)) .multilineTextAlignment(.center).minimumScaleFactor(0.001).padding()
}
}
how ever what is shown on canvas is the picture below and is trimmed on the right side.

This will achieve the look you are after:
Text("U")
.font(.system(size: 2000))
.minimumScaleFactor(.leastNonzeroMagnitude)

Related

Keeping layout consistent throughout several devices (SwiftUI)

I have a png background and I need to locate 5 texts on top of this png (see pic.). I am thinking of wrapping it all in a bundle of HStacks within one VStack. Something like this:
Vstack {
HStack {
Txt1
Txt2
}
HStack {
Txt3
}
HStack {
Txt4
Txt5
}
}
The question is how do I adjust it all so it is precisely in the spots like on the example picture. And more importantly, how do I keep this setup consistent throughout several devices? I tried to run on several devices and texts are all over the place, jumping up and down, left and right. There's got to be some kind of a simple geometry-like solution or the way to pin down the Vstack dimensions to my png size. Any advice?

SwiftUI view layouts with frame maxHeight and .infinity

How to layout views in SwiftUI in such way
I have input fields that I want to stretch to fill available space
This inputs are placed in VStack in such way that I am giving them frame(height: 40)
This VStack is inside white box which has frame(maxHeight: geometry.size.height * 0.8)
And the last white box is not adjusting to number of inputs in for VStack but rather takes 0.8 space and then this inputs are spread inside VStack instead (more spacing than needed is added.
I do not understand why such thing is happening.
FormView()
.frame(
maxWidth: geometry.size.width * 0.85,
maxHeight: geometry.size.height*0.85
)
Form View contains:
VStack(spacing: 4) {
FormInput(label: "First Name", input: self.$firstName) {
isEditing in
self.avoider.editingField = 0
}
.frame(height: 40)
.padding(0)
.avoidKeyboard(tag: 0)
I found the reason why sometimes View (layout) does not collapse to take smallest possible space, but instead expands to maxHeigh/maxWidth.
It happens when somewhere in between we use
GeometryReader { geometry in
VStack { ... }
}
Then those Views does not collapse and spread to maxHeight. I have this GeometryReader used inside .avoidKeyboard(tag: 0)
I also experienced this issue but managed to fix it by specifying idealHeight instead maxHeight and also adding a minHeight. So your example would be something like:
FormView()
.frame(
maxWidth: geometry.size.width * 0.85,
idealHeight: geometry.size.height * 0.85,
minHeight: geometry.size.height * 0.6
)
On a device with enough space, the ideal height will be used, on smaller devices the height will shrink but not to less than minHeight.

How to align the jointjs graph to the center / middle of the paper horizontally with the flow direction from top to bottom?

I have a graph generated using JointJs and it uses Dagre Layout provided by jointjs. Currently, the graph gets aligned from Top To Bottom which is the correct way but then the complete graph gets aligned to the left of the paper.
I need the graph to be aligned in the middle of the Paper Horizontally.
Current configuration used is this:
joint.layout.DirectedGraph.layout(graph,
{
rankDir: "TB",
marginX: 30,
marginY: 30,
clusterPadding: {
top: 10,
left: 10,
right: 10,
bottom: 10
}
}
I see that the option to make graph flow from Top to bottom is given rankDir: "TB". Is there any similar option which can align it horizontally to the middle instead of left which is by default? or any other way which can do so.
After calling directedGraph.layout you can then use Paper class to center the diagram.
const paper = new joint.dia.Paper({
height: 1000,
width: 1000,
...
});
const paperArea = paper.getArea();
const contentArea = paper.getContentArea();
paper.translate((paperArea.width - contentArea.width) / 2, (paperArea.height - contentArea.height) / 2);
This will effectively center the diagram, although care should be taken to avoid the content being larger than the paper size.

How to find bit length of text with specific font and font size

I'm developing NativeScript JavaScript code to create dynamic text marker for maps. I have the code working that creates a marker for a specific string. My next step is to take any given string, determine its height and width in bits, and create the marker sized to contain the text.
My problem is finding the size of the text, given the text string itself, the font size, and the font family.
It looks like getMeasuredWidth could work, except that the string must already be loaded on a page before that function will return a value. In my case, I simply need to compute the size; the text won't otherwise appear as such on a page (the text in the marker becomes an image).
Is there a way to do this?
var bmp = BitmapFactory.create(200);
bmp.dispose(function (b) {
try {
b.drawRect(
"100,34", // size
'0,0', // upper-left coordinate
KnownColors.Black, // border color
KnownColors.Cornsilk // fill color
);
b.writeText(
"Parking",
"2,25",
{ color: KnownColors.Black, size: 8, name: 'fontawesome-webfont', });
...
In the code above, the width of "100" of the bounding rectangle actually represents the bit width of "Parking" with a small amount of padding. What I want to does calculate the rectangle's height and width and not hard-code it.
Try this, finding label size without adding it to Page upon button click
export function onFindButtonTap(args: EventData) {
const button = <any>args.object;
const label = new Label();
label.text = "Hello, found my size?"
label.fontSize = 20;
(<any>label)._setupAsRootView(button._context);
label.onLoaded();
label.measure(0, 0);
console.log(`Width : ${label.getMeasuredWidth()} x Height : ${label.getMeasuredHeight()}`);
}
Playground Sample
Note: I didn't get a chance to test it with iOS yet, let me know if you hit any issues.

Extendscript: How to check whether text content overflows the containing rectangle

I am using Extendscript for Photoshop CS5 to change the text of a text layer. Is there a way of checking whether the text fits e.g. by checking whether it overflows after changing the content?
I created a solution that works perfectly fine :). Maybe someone else can use it as well. Let me know if it works for you too!
function scaleTextToFitBox(textLayer) {
var fitInsideBoxDimensions = getLayerDimensions(textLayer);
while(fitInsideBoxDimensions.height < getRealTextLayerDimensions(textLayer).height) {
var fontSize = parseInt(textLayer.textItem.size);
textLayer.textItem.size = new UnitValue(fontSize * 0.95, "px");
}
}
function getRealTextLayerDimensions(textLayer) {
var textLayerCopy = textLayer.duplicate(activeDocument, ElementPlacement.INSIDE);
textLayerCopy.textItem.height = activeDocument.height;
textLayerCopy.rasterize(RasterizeType.TEXTCONTENTS);
var dimensions = getLayerDimensions(textLayerCopy);
textLayerCopy.remove();
return dimensions;
}
function getLayerDimensions(layer) {
return {
width: layer.bounds[2] - layer.bounds[0],
height: layer.bounds[3] - layer.bounds[1]
};
}
How to use / Explanation
Create a text layer that has a defined width and height.
You can change the text layers contents and then call scaleTextToFitBox(textLayer);
The function will change the text/font size until the text fits inside the box (so that no text is invisible)!
The script decreases the font size by 5% (* 0.95) each step until the texts fits inside the box. You can change the multiplier to achieve a more precise result or to increase performance.
I haven't found a way to do this directly. But I've used the following technique to determine the height I needed for a textbox (I wanted to keep the width constant) before.
expand the textbox's height well beyond what is needed to accommodate the text inside it.
duplicate the layer
rasterize the duplicate
measure the bounds of the rasterized layer.
adjust the bounds of the original text layer as needed
delete the rasterized duplicate
Totally roundabout - but it did work.

Resources