Why does NSTextField with usesSingleLineMode set to YES has intrinsic content size of multiline text? - objective-c

I want to draw single line textfield with default border.
So I entered some multiline text into it(just for test for future cases) and set the flags
Swift:
textfield.usesSingleLineMode = true
textfield.maximumNumberOfLines = 1
Objective-C:
self.textfield.usesSingleLineMode = YES;
self.textfield.maximumNumberOfLines = 1;
But I got in console:
(lldb) po self.textfield.intrinsicContentSize
(width = 511.5, height = 174)
I've tested all lineBreakModes, including NSLineBreakByTruncatingTail.
Here is a field in IB:
Of course I can:
Overload intrinsicContentSize method
Filter strings keeping only first line
But it looks like a crutch =( Do you have any ideas how to fix it without crutches? Do you think it is an AppKit bug or my mistake?
PS In any case, thanks for attention.

This is not a bug. By default the NSTextField is trying to display as much text possible. I made a sample application, that contains a long line of text in the title of the NSTextField. Set it to "Uses Single Line Mode" and set line break to "Truncate Tail". I put leading, top and trailing layout constraints on the view. Now when i input the text into the text field, it will make the horizontal width of the window very wide. This is Autolayout in action.
To fix this you need to select the NSTextField, choose the Size inspector and set the Horizontal Content Compression Resistance Priority to a lower number. In the sample application I changed it from 750 to low (250).
Resize content view to an acceptable size, and you are off to the races.

Related

JSX (Photoshop) - document resolution in dpi

I'm working with a jsx script in Photoshop that resizes images to a specific size. The resolution is set at 200 dpi. After running the script, I can check this under Image > Image Size.
Problem is, depending on the image, it initially tends to show the resolution in dots/cm instead of dots/inch. The number itself is correct either way, but I'd like to see it mentioned there as the latter. Is there a way to realize this in JSX?
Thanks!
J
The easy way is to open your Info Panel by going to Window > Info, and then click on the x/y coordinates dropdown in the Info Panel and select inches. The dropdown is the + toward the lower-left of the panel, with the little down arrow at the bottom right of the + symbol (The plus is actually an x axis and y axis representing a coordinate plane). After that, when you check under Image > Image Size, it should show you all information in inches instead of centimeters. This should also show you inches anywhere else you look in Photoshop's interface, too, such as the rulers.
An exception would be that when using selection tools, such as the marquee tool with a setting like "fixed size" selected, you can override the units setting by typing in another unit in the Width and Height sections at the top of the window. You can even mix and match units, making a precise selection that is, for example, exactly 250 pixels (px in the Width setting) by 30 points (pt in the Height setting). And when you check your image size, it should still show you results in inches.
And finally, to answer your question as it was asked, the following code will change your rulerUnits preference without opening the Info Panel.
#target Photoshop
preferences.rulerUnits = Units.INCHES;
Note that if you want to write other scripts, you can change the rulerUnits to whatever units the script calls for, and then at the end of the script put your units back the way you had them.
#target Photoshop
// Save the original rulerUnits setting to a variable
var originalRulerUnits = preferences.rulerUnits;
// Change the rulerUnits to Inches
preferences.rulerUnits = Units.INCHES;
//
// Do magical scripty stuff here...
//
// Restore the original setting
preferences.rulerUnits = originalRulerUnits;
// List of rulerUnits settings available
// Units.CM
// Units.INCHES
// Units.MM
// Units.PERCENT
// Units.PICAS
// Units.PIXELS
// Units.POINTS

Two NSTextFields with interdependent widths in autolayout

I’m trying to put together what seems to be a simple case of two NSTextFields with dynamic width and fixed spacing in between. I cannot figure out an effective way to do so though.
I’m looking to get something like this:
The blue boxes are the NSTextFields. When more text is entered into one, it should grow and thus make the other one shrink, maintaining the lead space, trailing space and the spacing in between the fields. The first one should take the priority if both of the fields have too much text. Each field will also clearly have a maximum and a minimum possible width it can reach.
How would I go around handling this, preferably utilising IB autolayout as much as possible?
It seems to me that all of constraints you mentioned directly translate into interface builder --
First view has width >= something.
First view has width <= something
Same for Second view.
Space between views is fixed.
Second view wants to be as small as possible (have its width at 0) but this has lower lower priority than the previous constraints and lower priority than inner content size constraints.
The code I had to add to my view controller, after applying the constraints as per the ilya’s answer:
In controlTextDidChange (_controlWidthConstraint refers to the fixed width constraint of the input; it’s probably 0 by default for the second input):
// Get the new width that fits
float oldWidth = textControl.frame.size.width;
[input sizeToFit];
float controlWidth = textControl.frame.size.width;
// Don’t let the sizeToFit method modify the frame though
NSRect controlRect = textControl.frame;
controlRect.size.width = oldWidth;
textControl.frame = controlRect;
_controlWidthConstraint.constant = controlWidth;
The key lies in invalidating the intrinsicContentSize for the text field when text is input.
You can check a sample project here, to get you on the right track.

character is of string is always changing the position when ever I change the string value by using CCLabelBMFont

I update the score label when I'm playing my game and I display it by using CCLabelBMFont, when the score changes, each character of the score label always change the position of the label.
I want to keep it the same position!
Example: 00:01 take small space than 00:50; when the text change the CCLabelBMFont reposition the text again. help me , how to keep the same position?
Your bitmap font was created from a true type font that has a variable width.
Only fixed-width fonts like Courier will give you the same string width for the same amount of characters in the string. Strings drawn with non-fixed-width fonts will have varying width depending on the characters in the font, ie a 'w' character has greater width than an 'i' character.
Open FontBook.app (it comes with every Mac) and in the Collection panel select "Fixed Width" to see only the fonts with a fixed width. On my system I have these fixed width fonts installed:
FYI, Monaco is the default font used by Xcode.
It is hard to tell by the question, but my guess is that you are talking about the actual positioning of your label changing, meaning your alignment is not what you want it to be (justified left instead of justified right for instance).
Left Justified:
test
testtest
Right Justified:
test
testtest
If this is what you are talking about, you can change the text alignment by changing the nodes anchor point.
// for right justified
label.anchorPoint = ccp(1, 0);
When you are saying "always changing the position", do you mean "left side isn't staying in the same place"?
CCNode class has anchorPoint property, which determines which point of this node is "pinned" to the point in node's parent. Anchor point of (0, 0) means bottom left corner, (1, 1) - top right, (0.5, 0.5) - center. All positioning and transformations take place around anchor point.
Set anchorPoint property of your label to mean the point which you want to have "pinned" when content size of label changes. Examples:
if you want top left corner to be stationary:
label.anchorPoint = ccp(0, 1);
if you want the middle of left side to be stationary:
label.anchorPoint = ccp(0, 0.5);

auto adjusting the positions and height width of UILabel in iOS

I have designed my help page for my application,it contains some FAQs..so I have used UILabels for question and answer,I have adjusted,x,y,width and height exactly in the xib,leaving a gap between a question and answer and answer and next question.so totally I have some 10 question and answers,I have put them inside a scroll view.
But now, suppose the text changes dynamically, how can I adjust the positions and width and height,is a problem which I am not able to figure out, by using the below code,it adjusts the height and width of a particular label,if the text increases
NSString * test=#" It may come as a rude shock, but Facebook users should not feel surprised if tomorrow they come across their photos existing in the web world despite having deleted them personally long ago.";
m_testLabel.text = test;
m_testLabel.numberOfLines = 0; //will wrap text in new line
[m_testLabel sizeToFit];
but then, my next label will clash with it..is their any way so that all the labels get adjusted according if the width of any label increases or decreases?
Hope you all have understood my question..
Did you look into the below function, pass the font you have used and the size to which u want to constraint the label into.
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

Adding hardcoded value to contentSize

I've been trying to make my scrollview correctly fit it's content which includes a label, UIImageView, and textview. The textview sizes dynamically to different text, so I've made the scrollview's content size the same as the textview's:
sview.contentSize = (tview.contentSize);
That worked as expected, so my scrollview is close to the size I want, but I need to just add a static 180 pixels or so to make up for the label and image, which don't change size. I would guess it's an easy 1 or 2 lines of code but I can't figure it out. I've tried:
sview.contentSize += 180;
and
CGRect extra;
extra.size.height = 180;
sview.contentSize += extra.size;
and several other combinations to try to make it work but I keep getting errors like Lvalue required as left operand of assignment, or invalid operands to binary +. I'm sure I'm missing an easy solution, thanks for any help.
sview.contentSize = CGSizeMake(sview.contentSize.width, sview.contentSize.height+180);