Adding a custom font to macOS app using Swift - swift

I followed a bunch of tutorials but it doesn’t work: I simply want to add a custom font to a macOS app.
What I tried essentially:
Added the .ttf font-files to my project: Target Membership is set and I also made sure that the files are copied using Copy Files within Bundle Phases. After compiling I can see that all files are within the Bundle. So that seems to work perfectly fine.
Info.plist: I added Fonts provided by application and created an item for every font-file I want to add (values like myFont.tff).
I made sure that I use the correct font name. I installed the fonts on my system and configured a Label with Interface Builder so that it uses the desired font. I printed it’s value print(myLabel.font.fontName).
Confusing: If the exactly same font-file I want to add to the app is installed in the systems Fontbook and activated, everything works well. When I deactivate it, it doesn’t work. For me that indicates that I am using the correct font name.
I found ATSApplicationFontsPath and tried to add it to the Info.plist, but neither using a path (recommended by the docs) or values like . (which seemed to work for some people out there) worked out.
Appreciate any help!

I had a hard time getting this to work based on the previous answers, so I decided to write up an answer myself. This is based on previous answers by #ixany and #rob-keniger.
Create a folder named Fonts
Add fonts to the Fonts folder. Uncheck Add to targets and check Copy items if needed.
Add Application fonts resource path to Info.plist and enter Fonts.
Go to Build Phases and create a New Copy Files Phase.
Set the Destinations to Resources and Subpath to Fonts. Then add your font files to the list.

I solved my problem by accident.
I noticed that within the Bundle files, my fonts were included twice: They were copied to the "Resources" directory as well as to the subpath I declared in the "Copy Files" Build Phases.
I removed the fonts from my project, added them again (without checking the "Target Membership") and added them in the Build Phases so they were copied just to the subpath. After that it worked.
Additional notes:
Turned out that Fonts provided by application is a iOS only property so it is not needed for an macOS implementation.
Also, ATSApplicationFontsPath does not need any slashes. For example: Fonts should work just fine.
I had a difficult time finding the correct names for .ttf font files and sometimes discovered some strange behaviour: NSFont picked randomly fonts (regular, medium, bold...) from a font family without any code changes. By using .otf files instead I could solve that too.

None of the above worked for me in Xcode 12 beta 1 running BigSur but these steps did.
Create a Fonts folder for organization.
Add your fonts to the project. Be sure to check the macOS target!
Set Application fonts resource path to "." (no quotes).
No need to edit build phases or anything else.

THe value ATSApplicationFontsPath (i.e. Application fonts resource path) is relative to the Resources folder of your app bundle.
To see where your fonts are copied to:
In Xcode, expand the Products section under Project Navigator and click Show in Finder
In Finder, Ctrl-click on your app and click Show Resource Contents. Browse to the Resources folder and find your fonts there.

Xcode 12 to add custom fonts you have to exclude extension name from the string provided.
i.e.
.font(.custom("your font name", size:xx)) // works every time
.font(.custom("your font name.extension",size:xx)) // always fails
same is not true with Xcode 11.xx there fontname.extension is working.

Related

Custom font not loading in SwiftUI project after moving code to another project?

I had a SwiftUI project that I essentially messed up pretty bad and had to make a new project and transfer all the files over. It's working as intended except for my custom fonts aren't working and the default font is taking over. Here is what I did:
Copied my fonts folder into my new project
Checked the Target Membership box for my project and made sure that the path to the directory was referring to the new path, not the old path (bc it was before I changed it).
Included the names of both fonts in my plist, exactly how they were in the initial project's plist, in the fonts provided by application array.
Deleted and readded the fonts folder in my project's Build Phases (again, to make sure it was referring to the correct directory).
And yeah, still not working. Any insight as to what I could be overlooking? Because it was working completely as intended before I had to create the new project, and all other elements are working as intended.
If you are struggling with this in 2022 and using SwiftUI where there seems to be no info.plist in sight, then in addition to adding the Fonts capability in Target Signing and Capabilities, then dragging the file into your project and don't forget to check Add to Targets, and finally add your InsertFontFileName.ttf to "Fonts provided by application" which is now in your Info tab on the Target as seen in the image below. Also, call me crazy but before you drag the font in remove any special characters. In addition, don't be fooled by the auto-generated info.plist, add your new fonts via the image below, it'll auto-populate to that other plist. Maybe some of my steps are superstitious, but I spent enough time futzing around with fonts that I'm done thinking about it and I'll just follow my formula... and if that font doesn't work, it wasn't meant to be and I'll move onto the next font!
After that
.font(Font.custom("InsertFontFileName", size: 32, relativeTo: .title))
Although it looks like you have already done this, just go through the following checklist once:
Fonts (.ttf files) are present inside the project
Entry in info.plist file
Entry in "Copy Bundle Resources" under "Build Settings" of your target
If this is missing, add by clicking on the plus (+) icon in this section
Make sure you are using the font correctly (check spelling errors?)
var FontRegular : Font = Font.custom("Poppins-Regular", size: 16)
var FontBold : Font = Font.custom("Poppins-Bold", size: 16)
...
Text("Sample Text")
.font(FontRegular)

Why Custom fonts are not applied in Cocoa Application

Im working on Mac OS Application where I need to set custom fonts, so I did following things:
My Xcode version: 12.3
Added fonts to Application
Add Application fonts resource path Key to Info.plist and set the value "."
Added "New Copy file phase" and provided path Resource->Fonts and added fonts.
In my viewController set those fonts to Label programatically. Like this (titleLabel.font = NSFont(name: "Geogrotesque-Regular", size: 15))
Everything's works fine (fonts getting applied) when I run it at my end. But when I package it through archive or direct through product app folder and send it to my colleague. it doesn't work at their end. It seems very strange things are happening I gone through lot of articles and as per various suggestion I verified my implementation it seems no issue. Then what Im missing here?

Adding custom fonts to the keyboard extension ios 8

How can I add custom fonts to ios 8 Keyboard extenstion like this.Can anyone have a tutorial or example from which I can refer.Like this example https://itunes.apple.com/us/app/fontkeyboard-for-ios-8-use/id914787397?mt=8
1.In the above link they have the special characters as letters, Please refer below URL
http://fsymbols.com/letters/
2.In Your Extension,You have to maintain the two arrays one is with regular letter (A,B,C,D….)to show on your Keyboard
3.Second one is the Special character that you want to display in your target E.g..,(Ⓐ,Ⓑ,Ⓒ,Ⓓ..) (⒜,⒝,⒞,⒟….)
4.Use can directly copy the special characters from the above reference URL,and then you return the value of selected letter
5.If you want to give an options like the referred app,you need to maintain the array of those letters and return the value that you wanted to display for that selected letter.
Here is the keyboard button action,the insertText method used to insert your text to the target.
Please find my blog on how to creating third-party keyboards :Here's a link
Please find my sample project on github : Simple Custom Keyboard Sample
This is an old question but incase new people need the answer I will add mine. Gagan's answer (above) is quite elaborate and +1 for the github code; however, to my understanding the question is how to add font to custom keyboard, which could mean more than adding special characters to the keyboard keys (Gagan's answer), for example adding letters of languages not supported by apple.
In any case, to add a custom font to iOS keyboard extension, do the following steps:
Step 1. Drag/Add your ttf font to the Keyboard extension folder
(NOT to the host app) of your project in xcode.
Step 2. While importing make sure to check "Copy items if needed" and finish.
Step 3. Select Info.plist under Supporting Files section of the Keyboard extension folder
Step 4. At the end of the list add a string array
called "Fonts provided by the Application" xcode will autocomplete it
for you.
Step 5. Extend the newly added array and add the name of your
font/fonts eg. "Example.ttf"
Step 6. Now to make sure the font is copied to the final binary app, go to project properties and in the Targets section select the keyboard extension, then in the "Build Phases" tab and the "Copy Bundle Resources" subsection add/link the custom font.
That should get you a custom font in your keyboard extension!
Notice that in the steps the Keyboard extension is mentioned repeatedly on purpose, because thats the catching point when adding custom font to the extension compared to adding font to normal applications and it should not be confused with host app of the extension. iOS Custom Keyboard project in xcode usually comprises a host app which is pretty much a normal iOS app and the actual keyboard extension, both are displayed as folders in the Project Navigator.
If the custom font is needed to be used in the host app, then the steps are similar, only then make sure the destination is the host app folder and once again select the host app Target in the project properties when adding to the Bundle resources.

Unable to change location / path settings after migrating Xcode project

I've migrated an Xcode project (iOS app) from one mac to another (same Dev Account and Code Signing preferences). Now the build fails and I get errors stating that certain files (MainWindow.xib, MyappViewController.xib and InfoPlist.string) don't exist. I've already read that several people have had this problem before and tried out the answers they got, but nothing seems to work.
As I understand, the problem lies within the path preferences for the NIB files. The error messages give the files' path as Users/Meonmyoldmac/etc - which I should change, because it's an absolute path and therefore doesn't make sense on another computer. But: when I try to open those files under Groups & Files their location is already set to 'Relative to group' and their path is given as Users/Meonmynewmac/etc. - which is exactly how I actually want it to be. (Oddly enough, the file type is listed as 'Default - Unknown' )
I've already tried…
- cleaning the project
- deleting those files from the project and putting them back in again
- restarting Xcode several times
that's possibly important:
- I'm talking about a Universal iOS App, yet only iPhone files are affected; their iPad equivalents work fine
- I changed the app localization to German, so the mentioned files are located in a folder called de.lproj
- I created the project with Xcode 4 on my older Snow Leopard Mac and use Lion/Xcode 4.2 on the new one - does that play any role here?
Thanks in advance, Fruity
If you have absolute paths to some of your files, you'll need to change them to relative paths:
In the Project Navigator, locate the missing files (colored red for not being found) and highlight one of them.
Show the File Inspector
Under Location change Absolute Path to Relative to group or Relative to project,
Then next to the path, there's a little white icon, click it and choose the file's location.
Right-click on the files in Finder, select Get Info. Check that you have permission to read the files.
Edit: Just noticed the error messages refer to the old path, so it can't be a permissions problem.
Groups can have paths set as well. Select the groups and verify that their paths are correct.
In XCode 4, when you have all three panes open, select the file in the left most pane. In the right most pane, select the white document icon at the top, looking for the header "Identity and Type." Under the popup for "location" is the name of the file. To the right of that name is a tiny icon like a window. Click on that, and you can set the location of the file.
I performed the terminal search suggested by Jim yesterday, found some 'source tree: absolute' entries in project.pbxproj and tried to manipulate them, which didn't work - couldn't even open the project in Xcode afterwards - so I called it a day.
Just now I did what I already tried yesterday before posting my question: I deleted the files from the project and copied them back in again. That miraculously eliminated all red warning signs from my project and just gave me a nice green SIGABRT when I tried to run it on the simulator. Cleaned project, restarted Xcode - perfect. Oh, and I checked the targeted device family setting, found that it was set to iPhone and switched it to iPhone/iPad - no idea if that was part of the issue.
I'm not sure if that's really an answer to the problem - but the problem has vanished...
Thanks for your help!
A less-actions solution. You can change manually in the project definition file.
Close xCode
Open .xcodeproj file in a text editor: in fact it's a folder, so edit in a text editor the inside file: project.pbxproj.
Search for the string: absolute (for sourceTree param)
For each entry (file with a absolute path set), change absolute to group.
And change the path parameter to a relative path. example:
path = en.lproj/PilotInfoViewController.xib;
- Save the file and reopen xCode.
PS: Make a backup copy of your project file before doing this manipulation.

Can an Xcode project with multiple targets have different Settings.bundle's for each target?

I have a settings bundle in an iPhone app which has several subtle variant targets.
The problem is I need to customise some strings in each settings bundle to make them appropriate for each target. It appears that if the Settings bundle is named anything other than Settings.bundle it won't pick up the bundle (understandable, can I specify in a plist somewhere the alternate name?).
If I try and put them in different folders and call them the same thing Xcode gets horribly confused and lets you edit "2 files" that are actually the same single source.
I see no problem. For every target, create a specific folder with files for this target. Now create a group in Xcode for every of those folders and drag each of the new Settings.bundle directories to the corresponding group. When adding the bundles to the project, make sure that every bundle is only built (included) for its target by checking the appropriate box.
AFter you do what MrMage said which is correct.. i had an issue where the Root.plist would not show up under the Settings.Bundle for a specific target.
You have to let xcode know what the setting.bundle file is... click on the settings.bundle that wont show the Root.plist, then go to file inspector
Alter the file Type drop down to be applicationBundle ... now the Root.plist shows up.