I have a UIPrintInteractionController that is created programatically. It is set to pull a pdf from my servers, and print said pdf. My question is how can I change the font of the view. I already have set the navbar font in my app delegate (so the font appears on all views), but this doesn't apply to the view. Any help is greatly appreciated. Thanks!
I figured it out. Create an extension of UILabel like so
extension UILabel {
var substituteFontName : String {
get { return self.font.fontName }
set { self.font = UIFont(name: newValue, size: self.font.pointSize) }
}
}
The in AppDelegate.swift, use this extension to change the font of every label in the entire application, INCLUDING the UIPrinterInteractionController.
UILabel.appearance().substituteFontName = "Font Name Here"
Killed two birds with one stone.
Related
I'm developing a macOS rich-text editor that applies pre-defined style for each line of the text view.
To format the lines, I'm using NSAttributedString, then, I'm inserting that string into my UITextView. To make things easier, I'm using a tool called SwiftRichString.
My code looks like below. It's straight-forward and works fine.
import Cocoa
import SwiftRichString
import AppKit
class ViewController: NSViewController {
#IBOutlet var textView: NSTextView!
override func viewDidLoad() {
super.viewDidLoad()
// Format the string
let style = Style {
$0.font = NSFont(name: "Arial", size: 20)
$0.color = NSColor.black
$0.alignment = .center
}
let attributedText = "Hello World!".set(style: style)
// Add formatted string to the text view
textView.textStorage?.append(attributedText)
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
Current situation:
User is typing a formatted line. Then when user hits Return and types something, format of the new line returns back to the default style of the UITextView.
What I want:
User is typing a certain formatted line, then he hits Return. The next line should be formatted to another pre-defined style on-the-go.
Example:
User is typing the Title line. Current style is (Arial, bold, 20pt).
He hits Return.
Next line should be styled as Normal Text using a pre-defined style (Arial, 12pt).
Important Note:
In my above code, I was able to format the line easily because it's hard-coded. My real issue is, how can I instantly format the next line, because the next line will be entered by the user. The style should be applied to the next line before user begins writing it.
Okay, I just figured out how to use typingAttributtes to solve this question (thanks to #Larme for the hint).
// Define next attributes
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: NSColor.red,
.font: NSFont(name: "Arial", size: 12)!,
]
// Assign attributes to the text view typing attributes
textView.typingAttributes = attributes
Very easy!
Pardon off topic. If you're making a text editor, you may consider using a table view, where each text line is a cell - this is extra work for you as a programmer but it'll boost the performance significantly. That's how Xcode editor is built.
Maybe you might use optional func textViewDidChange(_ textView: UITextView)
https://developer.apple.com/documentation/uikit/uitextviewdelegate/1618599-textviewdidchange
and after the change, just parse the text, find new lines, split them and apply all styling you want
Is it possible to customize the prompt string at all?
I have hooked up the navigationBarItem to my ViewController and added a string as the "Prompt" via IB. There are no properties following the prompt class that allow me to alter the contents of the string, color, etc etc. I was wondering if anyone knows any other possible work around for this problem?
It is possible to customize the prompt appearance with one big limitation, the style of the prompt and of the title will always be the same.
Assuming you are in a UIViewController presented within a navigation controller with a navigation bar, you can do this:
guard let font = UIFont(name: "Helvetica", size: 17) else {
return
}
let navigationBar = navigationController?.navigationBar
navigationBar?.titleTextAttributes = [NSFontAttributeName: font,
NSForegroundColorAttributeName: UIColor.blue]
You can also use the UINavigationBar.appearance() method to have this configuration on all the navigation bar prompts in your app.
I'm pretty new to iOS development and I was asking my self if it is possible to use localized strings from my "Localizable.strings" file directly into the storyboard.
For example in Android you can do it from the XML file like this:
android:text="#string/notConnected"
I understood that you can make a localized version of the storyboard, but having different strings files and different storyboards looks pretty ugly to me.
So is it possible to have only strings files and use what I need into the storyboard? Preferably without setting it from code?
EDIT:
This is practically what I want to do:
So is this possible? Is there a legit way to call a string from there like in Android?
I think being able to localise Strings in the storyboard is of significant advantage. I don't agree with #elk_cloner that hooking up IBOutlets for every UILabel is the way forward.
One way of getting it to work is using an #IBInspectable property on a UILabel subclass:
class LocalisableLabel: UILabel {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
text = NSLocalizedString(key, comment: "")
}
}
}
In the storyboard set the custom class:
In the attributes inspector the localisedKey field will appear and you can just add your key here.
That's it!
EDIT:
You can localise UIButtons the same way, BUT if the text in the storyboard's title field differs from the localised String (which it will in other languages) the setting of the title will animate.
To fix this, put the setTitle in a performWithoutAnimation block:
class LocalisableButton: UIButton {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
UIView.performWithoutAnimation {
setTitle(key.localized, for: .normal)
layoutIfNeeded()
}
}
}
}
In addition to Leon's answer, you can get rid of the need for an explicit subclass by using an extension:
extension UILabel {
#IBInspectable var localizableText: String? {
get { return text }
set(value) { text = NSLocalizedString(value!, comment: "") }
}
}
According to your requirement it's not possible but
You don't need different storyboards for localization
Suppose you want to localize a label string.
Draw and outlet and change text using
mylabel.text = nsLocalizedString("THIS_IS_MY_STRING",nil);
Of course in your localization file there will be a line.You must have different files for different language.Suppose you have a file for english and there must be a line.
"THIS_IS_MY_STRING" = "This is my string";
When you compile your app, that function will use mapping to localize your app.
Edit:
If you want detail information please have a look at these tutorials
internationalization-tutorial-for-ios-2014
and ios-localization-tutorial
There are some online script(e.g localize.py) which will help you to automatically search all of your code and find out nslocalizedString function and make lines in your localizableString files. like this.
"THIS_IS_MY_STRING" = "THIS_IS_MY_STRING"
and later on you just have to write actual string there. :)
Make a button class and set #IBInspectable attribute to the button class
class Button: UIButton {
#IBInspectable public var referenceText: String = "" {
didSet {
self.setTitle(NSLocalizedString(referenceText, comment: ""), for: .normal)
}
}
}
Then in the storyboard you can set referenceText
The button text will be "Sign In"
Another possible way is to localize the storyboard and simply change the values for labels and buttons directly on the .string file.
First select the storyboard, and click on localize:
Then you'll be able to select the languages you want.
This way you'll be able to continue developing on your language of choice and simply edit the .string file that is generated
for button
extension UIButton {
#IBInspectable var localizableText: String? {
get { return titleLabel?.text }
set(value)
{
setTitle(NSLocalizedString(value!, comment: ""), for: .normal)
}}}
Very much like how we can set the Global Tint in Storyboard, Is it possible to set the global font-family as something else?
For example, I want to change the Global/Default Font from System to Source Sans Pro 16pt. However, what I have to do (to my knowledge) is one of the following:
Change font of each label, button, textField, etc. in Storyboard.
Set it via Swift ViewDidLoad Code (like this question) or through extensions as explained in this question
My Problem with (2) is that I do not get Visual Feedbacks like in (1) using storyboards. On the other hand, it is also not very eloquent as I have to manually set it anyway.
So, is there a way to change/set the default Storyboard font?
You can use the Appearance API, to ensure that all controls have the same font (at runtime)
Look at this question as to how to set the font for UIButton with Appearance.
For UILabel and UITextView, do the following. This can be done in AppDelegate application(_:didFinishLaunchingWithOptions:)
let labelAppearance = UILabel.appearance()
labelAppearance.font = UIFont.myFont()
let textFieldAppearance = UITextView.appearance()
textFieldAppearance.font = UIFont.myFont()
The previous solution, however will not update storyboard.
To see the changes visually on storyboard, you can look into the function
prepareForInterfaceBuilder()
Here is an answer that explains how to get it visually updated in storyboard, but for this you will need to use custom classes for your textFields, buttons, etc.
Code Example as per above link:
#IBDesignable
public class MyUILabel: UILabel {
public override func awakeFromNib() {
super.awakeFromNib()
configureLabel()
}
public override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
configureLabel()
}
func configureLabel() {
font = UIFont(name: Constants.DefaultFont, size: 40)
}
}
i just want to modify the size of character of the UITextView. until now is possible to attach the string, but i Try to change the dimension: is not possible.
As i searched into the Forum i found that some people got it selecting Editable and deselecting it. Other people got it by selecting Selectable from the View properties. Then i tried this way... no way to change. Only Plain text.
import UIKit
#objc(TextControllerSwift) class TextControllerSwift: UIViewController {
var selectedMovie: String?
var textPlaying: String?
#IBOutlet weak var textMuseum: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
realPlay()
}
func playText(textSelect: String) {
textPlaying = textSelect
}
//Giving the time to Segue method to wakeup.
func realPlay(){
var textRoom: String?
//reading the file .txt
let path = NSBundle.mainBundle().pathForResource(textPlaying, ofType:"txt")
if (path != nil){
do {
textRoom= try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
//here i'm getting the string.
}
catch {/* ignore it */}
//i tried it these options...
textMuseum.editable=true
textMuseum.selectable=true
textMuseum!.text=""
//Got the text, now i put into UiView
textMuseum.font = UIFont(name: "Arial-Unicode", size: 50)
textMuseum.text=textMuseum.text.stringByAppendingString(String(textRoom!))
}}}
hmmm where am i getting wrong?
because i changed the textMuseum font. Should i free some Costraint on the UITextView Object put in the StoryBoard? also with the editable and selectable removed the result is the same. why?
thank you for every help.
EDIT:
Added Git Repository - No Working Video as i deleted this part. To see the problem just click on uisegmented "testo" and select play or the table.
https://github.com/sanxius/TryText.git
After reviewing your source code:
Make UITextView selectable: textMuseum.selectable = true
If you want to use custom font then do not forget it's file name to add it to Info.plist Fonts provided by application array.
Use existing font name. There is no font with name Arial-Unicode. Arial-Unicode.ttf is file name not font name.
You can find your font name by listing all loaded fonts with:
for familyName in UIFont.familyNames() {
for fontName in UIFont.fontNamesForFamilyName(familyName) {
print(fontName)
}
}
Also iOS has built-in Arial font that can be loaded by UIFont(name: "ArialMT", size: 50). So you do not need to add your Arial-Unicode.ttf.