Custom font with dynamic type in interface builder - swift

I have several views in my Storyboard which have UILabels. These labels are set to Automatically Adjusts Font and use text styles like Body or Headline.
I know there is a programmatic approach as such:
https://useyourloaf.com/blog/using-a-custom-font-with-dynamic-type/
let label = UILabel()
label.font = scaledFont.font(forTextStyle: textStyle)
label.adjustsFontForContentSizeCategory = true
However, given that I have already laid out my labels and set their text styles, is there a way to use a custom font AND text styles from within interface builder? Or maybe somehow override their font-family while respecting the text style already set on them?

No, you'd need to use the programmatic approach. However, it is easy to write a little loop that runs through all your labels and for each one, fetches the dynamic type "role" already set in interface builder and substitutes a UIFontMetrics value based on that "role" and the desired custom font.

Related

Change font face/size of the top GTKWindow?

I'm trying to use .NET Core GTK. For WinForms, we can select the form, and then click the Font property to change the font face or size within the Form designer. If we change the top form's font, it is applied to all the child controls on the form.
I wanted to do similar thing in Glade, but I cannot find a "Font" GUI in any of the attribute tabs.
Is this possible with GTK#?
If so, can it be done within Glade?
If the answer to 2 is no, can it be done in the code?
Yes this is possible in both GTK and Glade, although some code will be required to change all the forms font.
In GTK you will be using the GtkFontChooserWidget. This should let you choose between fonts.
In Glade, when you are using the attributes tab you are able to change font size with the Scale attribute. I haven't yet figured out how to change the actual font through those attributes yet. Thankfully there is a workaround. Instead of using Attributes, use Markup. Markup works just fine for both font size and font style.
Markup Example
<span font='36' face='Georgia'>Markup</span>
Assuming you are using a GtkComboBoxText to list possible fonts and button for selecting, you would just need a handler that would go through each of the labels and change the font to the designated one.
def when_visible(window):
"""
This is where per-window initialization takes place.
Values to be displayed are populated into their widgets.
"""
global FONT_FACE
name = Gtk.Buildable.get_name(window) # Window currently on
if 'font_select_screen' = name:
font = BUILDER.get_object('fontEntryCombo')
FONT_FACE = font.get_active_text()
elif 'random_screen' = name:
label1_text = "<span font='36' face='{}'>Label</span>".format(FONT_FACE)
label1 = BUILDER.get_object('label1')
label1.set_markup(label1_text)

How to gray selection highlight when NatTable not in focus

Some lists and tables gray out their selection when they lose keyboard focus.
In the presence of multiple lists/tables, this helps communicate to the user which selection is active.
Is there an easy way to do this with NatTable?
The best I've come up with so far is to flip between different attributes for DisplayMode.SELECT as focus comes and goes -- but I'm not sure I can do that after NatTable.configure() has been called.
Yes you can change configuration attributes dynamically after NatTable#configure() has been called. That is a common approach for dynamic changes. Another approach would be to configure a selection style for a special label and apply that label only in case the table is active. This approach can be seen in this example.
https://github.com/eclipse/nebula.widgets.nattable/blob/master/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_505_Selection/_5054_SelectionProviderExample.java
I have this working, after #DirkFauth's answer. This answer includes some specifics.
After the table has been configured with NatTable.configure(), you can modify the configuration not with NatTable.addConfiguration(IConfiguration), but instead by calling IConfiguration.configureRegistry(IConfigRegistry). For example:
myConfiguration.configureRegistry( myTable.getConfigRegistry() )
Within that implementation of configureRegistry(), you can set the style for selected and anchor cells:
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE,
selectedStyle, DisplayMode.SELECT, GridRegion.BODY);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE,
anchorStyle, DisplayMode.SELECT,
SelectionStyleLabels.SELECTION_ANCHOR_STYLE);
When the table is inactive, selectedStyle and anchorStyle can be modified clones of their usual setting. For example:
private static Color myInactiveColor = ...;
public static Style makeInactiveBodyCellStyleFrom(#Nonnull Style style) {
Style rv = style.clone();
rv.setAttributeValue( CellStyleAttributes.BACKGROUND_COLOR,
myInactiveColor );
return rv;
}
Similar work can be done for the styles of selected row and column headers.

Two different colors inside an UITextField

I have an UITextField where the initial text is "username.mysite.com". The default color (Black) is set.
I would like to have "username" with a different color like gray. Is it possible?
User can click the "Clear Button", than the placeholder is "url".
Can't be done with a UITextField directly. Your basic two options are:
Use a UIWebView masquerading as a text field. This is easy, but is a sledge hammer and can incur performance penalties in certain use cases.
Use Core Text to display a duly configured NSAttributedString. Though the link appears to be for Mac OS, Core Text exists on iOS too. The framework is very powerful but has a steep learning curve and doesn't support editable text out of the box. There are, however, various open source libraries that might of help getting started (e.g. DTCoreText. OHAttributedLabel).
No, it's not possible with default settings.
you can change the colour of placeholder, by accessing following private property, it will show warning to you, but it will be going to work very well.
[aTextField setValue:[UIColor yellowColor]
forKeyPath:#"_placeholderLabel.textColor"];
There is another way also present for doing this, you can override drawPlaceholderInRect method with your custom implementation.
UITextField has an attributedText property, that can be set to any NSAttributedString with any colors you like. For example:
// Create a string:
let attribString = NSMutableAttributedString(string: "username.mysite.com")
// Set the grey color to the "username" portion of the string (the black color is the default for the rest):
attribString.addAttribute(.foregroundColor, value: UIColor.gray, range: NSRange(location: 0, length: 8))
// Set the attributed string to your text field:
textField.attributedText = attribString

One label, two different fonts?

I need to format text in a label like this:
username: some text from this user. This will
create additional lines of text that will go
on and on and on.
Where "username" is bold. This will go into a UILabel, which is in a custom table cell. Is there a way to get this type of layout?
For this relatively simple case, you might be able to fake it. Have one label with the bold username, and another label with the plain text in the same position. Insert enough spaces before the plain text to leave room for the username. You can use UIStringDrawing methods to measure the bold text and the spaces.
CGSize usernameSize = [theUsername sizeWithFont:theBoldUsernameFont];
CGSize spaceSize = [#" " sizeWithFont:thePlainCommentFont];
NSString *indentedComment = [NSString stringWithFormat:#"%*s%#" , (int)ceil( usernameSize.width / spaceSize.width ) , "" , theComment];
If you use plain UILabel it's not available. Use two labels for this task.
You need to use either a UIWebView or CoreText to do this kind of advanced text layout. A web view has a lot of overhead but is most flexible and you can't use it effectively in a UITableView cell. CoreText is low level and not that well documented. You could ditch the table view and just lay out the table with CSS and HTML in the web view, which is how I do it.
You can still use a UITableViewCell but have the cell use a UIWebView subview. Set up a custom cell subclass with a clever setter method that allows you to send nsstrings to the method with turns those into a pretty formatted view.

How to get the same UITableViewCell layout as in the Address Book app?

I currently have a custom UITableViewCell which contains a few labels, and an image.
The "main" label is used to display people's names. Currently, I'm styling it in bold text.
What I'd like to do (to gain some space and readability), is to mimic the Address Book app cell style, that is: first name in light text, and family name in bold text.
Is there a way to do this using the same UILabel? Or, should I use 2 different UILabels? How should I layout them, without knowing their sizes?
Thanks in advance for your assistance!
See this sample code from atebits:
http://atebits.cachefly.net/blog/FastScrolling/FastScrolling.zip
It does something similar to what you want.
You can use the built-in UITableViewCellStyleValue2. From the UITableViewCell.h header file:
UITableViewCellStyleValue2, // Right aligned label on left with blue
//text and left aligned label on right (Used in Phone/Contacts)
Pass this into your [[UITableViewCell alloc] initWithStyle:...] method.
I think it's table view cell with UITableViewCellStyleDefault style. If you'd like to use different font attributes then you need to use different labels (because there is no attributed strings yet). To calculate size of these labels you should use following method:
- (CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode;
or any relevant from NSString(UIStringDrawing).
Also, you can use custom strings drawing instead of UILabel.