I have a UITextField for which I would like to assign a custom font and font-size like this
self.txtEmail.font = UIFont("HelveticaNeue-Light", size: 24)
When I start the app everything looks good. My placeholder text gets the new font and if I click on the input field and start typing, the text has the new font. However, when I click somewhere else and the input field lose focus the font is reset to the default font. What I find even more strange is that I only have set this default font for UILabels and not UITextField by adding this line in the application method inside AppDelegate. If I try to set the default font for UITextField nothing happens.
UILabel.appearance().font = UIFont(name: "HelveticeNeue", size: 18)
So my question is why I get the behavior where the UITextField has the correct font until it gets content and lose focus.
I have 1 general remark on UI elements' appearance management and one more on UITextField.
A) Appearance:
The documentation says:
To customize the appearance of all instances of a class, use appearance to get the appearance proxy for the class.
In fact, that means that your changes will be applied to every instance of UILabel that enter your application window (as an iOS app has only 1 "public" window). If you want to customize the appearance of labels contained within a particular container class (e. g. inside UIView), you should consider using
+ appearanceForTraitCollection:whenContainedIn: (unfortunately, it's been deprecated since iOS 9.0). A much safer way is to use inheritance for your purposes as follows: MySpecialLabel -[inherits from and applies custom style attributes within its initializers and/or the awakeFromNib: method]-> UILabel.
B) Why is it related to UITextField?
That's because UITextField utilizes UILabels under the hood (like _placeholderLabel and _promptLabel).
I hope it will help you solve your problem.
Related
Go to "Settings"-> "General"-> "Accessibility"-> "Larger Text" to change the font size.
Open my app, now all the UILabels and UIButtons do change accordingly. I want to disable it and want to keep as it is regardless of the large font or small font on the setting. I have made everything programmatically. How can I disable this?
myLabel.adjustsFontForContentSizeCategory = false
Although this depends on the font that you're using. See more info here: https://developer.apple.com/documentation/uikit/uicontentsizecategoryadjusting/1771731-adjustsfontforcontentsizecategor?language=objc.
Specifically, this part:
For this property to take effect, the element’s font must be vended
one of the following ways:
It must be vended using the preferredFontForTextStyle: or
preferredFontForTextStyle:compatibleWithTraitCollection: method with a
valid text style.
It must be vended using one of the scaling methods from UIFontMetrics.
I have this issue with a custom UIView where I have a UIButton subview, I want to set the button's text on initialization based on some condition like this:
- (void)awakeFromNib {
[super awakeFromNib];
//check for some conditions
self.testButton.titleLabel.text=#"Some Title";
}
Nothing happens and the button's text is the same as defined in the nib file, however if I change the implementation to:
- (void)awakeFromNib {
[super awakeFromNib];
//check for some conditions
[self.testButton setTitle:#"Some Title" forState:UIControlStateNormal];
}
It works as expected.
Can somebody please explain to me the difference between the two approaches? and when to use each?
EDIT:
the suggested answer doesn't explain my situation, I tested changing the button's text from another button's action like this:
- (IBAction)otherButtonClicked:(id)sender {
self.testButton.titleLabel.text=#"Some Title";
}
and the button's text changed. I just want to understand that behaviour.
Exact answer is
titleLabel
Do not use the label object to set the text color or the shadow color. Instead, use the setTitleColor:forState: and setTitleShadowColor:forState: methods of this class to make those changes.
The titleLabel property returns a value even if the button has not
been displayed yet. The value of the property is nil for system
buttons.
setTitle
Use this method to set the title for the button. The title you specify
derives its formatting from the button’s associated label object. If
you set both a title and an attributed title for the button, the
button prefers the use of the attributed title over this one.
At a minimum, you should set the value for the normal state. If a
title is not specified for a state, the default behavior is to use the
title associated with the UIControlStateNormal state. If the value for
UIControlStateNormal is not set, then the property defaults to a
system value.
Title label access is given to adjust other properties of the label such as font but setting titleLabel text does not work.
It is because UIButton class has inner implementation to set the text based on different states of the button like selected/highlighted etc which overrides label text.
The accepted answer is correct, I just add this here to elaborate a bit (comments are too short)
There's not much to explain here. The title is simply not meant to set the text at all. My guess is that the internal workings of UIButton make it save the text somewhere else as well (for different states). It uses a normal UILabel to eventually display that, because that's convenient and easy to understand. Setting the text of that does not change the button in all cases, which probably ultimately depends on the drawing cycle. I assume when it's drawn, laid out, or the like it "replaces" the label's text with its other saved variant at some point.
Now you might wonder why Apple did then expose the UILabel and thus seemed to make the text editable then.
Legacy is probably one aspect of this decision (IIRC you could once set the button's title that way). Although old code doesn't result in the desired behavior, it at least didn't crash immediately. Also, a lot of code simply wants to get the text and expects a label, that works perfectly fine as ever.
Second, designing it totally different seems overkill. To avoid that, they would have to use a subclass of UILabel which prevents you from setting the text or something and use that. Or skip it (and thus legacy support) completely and only offer the setTitle:forState: method. That seems like a bit much for a simple text container like a Label.
Ultimately it's a design choice made by Apple. You can't set the title text directly and there's no case in which you should do it any way other than by using setTitle:forState:
I am creating a simple quote app as a learning experience and need to format it to look better.
I am trying to make the background have a "white square" where the text is and make the text black. Just like the Twitter app has when you click on a tweet.
What is the best way to do this and what should I start with?
I know it is very simple, I'm only 15 and am trying to learn iOS. As you can see I have a server and have the app up and running, just want to format before I call it complete. Thanks! :)
-Henry
This will depend on how you created the label that displays your text, but you can do this very easily:
If you created your UI in a Storyboard / XIB file in XCode: assuming you dragged out a UILabel or UITextView, you can use the Attributes Inspector to set the text color and the background color (in the View section) of the element holding the text.
If you created the label (or text view) in code, you can set the textColor property and the backgroundColor properties programmatically.
Here's an interesting problem for you:
We are in the process of re-skinning our entire app, which consists of over 100,000 lines of code and almost 100 XIB files. The new design requires (almost) every label in the app to use a new custom font, whereas the old app uses the default font of Helvetica Neue.
What is the most efficient way of changing as many of the UILabels as possible? We don't want to have to manually change thousands of labels both in code and in XIBs (which is especially difficult because we are using a non-system font).
We've discussed swizzling UILabel's creation methods to default to using the new custom font, which would still allow for the few labels that would remain in Helvetica Neue to be customized after creation.
Thoughts?
Take a look at NUI https://github.com/tombenner/nui.
You can customize a lot controls with it using a CSS-like stylesheet and implement it via subclasses or categories.
You should probably subclass UILabel and override either an initmethod of your choice, or awakeFromNib, and set the custom font there. Then you can go through the xib, either manually, or open it up in a text-editor and add a line like
<string key="X.CustomClassName">YourCustomLabelClass</string>
To set the specified label to your custom label class.
Swizzling is a good option . If you want to do it other way and have problems with custom fonts, I usually make a trivial subclass of UILabel that changes it's font in awakeFromNib for each custom font so I can lay them out in the interface builder.
But... This comes to my mind:
[[UILabel appearance] setFont:xxx];
I am not sure how you would deal with keeping the size, though. Perhaps swizzle is the best choice
I want to create a custom input view, some of whose buttons insert "icons" into the selected UITextField, like the "RSS" or "Reader" icons which sometimes appear on the right hand side of the URL input field in Mobile Safari. I want the icons to be intermingled with the text and for all intents and purposes (like selection, cut and paste and deletion) behave like normal character glyphs.
Is there a name for these icons? Is there an API for creating them or do I have to build this entirely from scratch?
The leftView and rightView properties (instances of UIView) of the UITextField class are exactly for this purpose, and you can control their behaviour using the leftViewMode and rightViewMode properties. I suggest you to read the UITextField class reference for further details.
According to this question, what I want is an NSTokenField and there's not one available in stock iOS. However, there are some implementations on GitHub.