Open Slodin opened 4 years ago
This is another problem I'm attempting to solve. When typing the name of an icon in English, the font auto-translates it to the appropriate icon, rather than just using Unicode. I have not yet been able to figure out why.
Are you initializing your UIBarButtonItem
in Storyboard or inside a class?
This is another problem I'm attempting to solve. When typing the name of an icon in English, the font auto-translates it to the appropriate icon, rather than just using Unicode. I have not yet been able to figure out why.
Are you initializing your
UIBarButtonItem
in Storyboard or inside a class?
It is a UIBarButtonItem in the Storyboard, but used in a viewcontroller class. I thought String.fontAwesomeIcon(name) is used to translate the icon into a string, but it seems to affect the entire title anyways with or without calling that function. It's almost as if it's matching anything that contains certain key words. I was trying to write "Routes Prev", it became: route Icon + "s Prev".
You're correct, and this is a source of investigation at the moment. I have yet to determine what it is about the font that causes actual text to be translated into an FA icon.
Currently, when using String.fontAwesomeIcon(name:)
, it's basically just the same as using FontAwesome.x_icon_name.unicode
Until I can solve this issue, my recommendations are:
UILabel
and UIButton
both have attributed title options.Here's a short code snippet to get you started with FA+NSAttributedString
let button = UIButton() // or link to one defined in your Storyboard
let label = UILabel()
// Note this MUST be Mutable for us to be able to apply an attribute
let string = NSMutableAttributedString(string: "Sync " + .fontAwesomeIcon(name: .chevronRight))
// If your icon is the first char in the text, use range: NSRange(location: 0, length: 1)
string.addAttribute(.font, value: UIFont.fontAwesome(ofSize: 18, style: .regular),
range: NSRange(location: string.length - 1, length: 1))
button.setAttributedTitle(string, for: .normal)
label.attributedText = string
Hope this helps!
Thanks for your reply, I did figure out a similar thing to yours for labels and buttons. However, UIBarButtonItem is a different story since it doesn't take attributed strings. Then I realized I can just stuff a button or label into the UIBarButtonItem...
So I figured a workaround for UIBarButtonItem, I didn't look into this problem until earlier since I had to do many more translations and this problem only happens at a few places for my project...I hate IOS localization lol. It's a super roundabout way...But I don't have any better ideas rn
View Controller
let routePreviewButton = UIBarButtonItem()! //linked from storyboard
let routeButton = UIButton()
//Add your button target, users will touch this instead of the UIBarButtonItem now in my testing
routeButton.addTarget(self, action: #selector(navToRoutes), for: .touchUpInside)
let routeIconTextAttr = generalHelper.getFAIconWithText(name: .map, size: 15, style: .solid, text: "Routes Prev.")
routeButton.setAttributedTitle(routeIconTextAttr, for: .normal)
routeButton.setAttributedTitle(routeIconTextAttr, for: .selected)
routeButton.sizeToFit()
routePreviewButton.customView = routeButton
GeneralHelper.getFAIconWithText
let icon = NSMutableAttributedString(string: String.fontAwesomeIcon(name: name), attributes: [.font: UIFont.fontAwesome(ofSize: CGFloat(size), style: style)])
let textToAppend = NSAttributedString(string: text, attributes: [.font: UIFont.systemFont(ofSize: CGFloat(size))])
icon.append(textToAppend)
return icon
This approach still requires coders to adjust the button's appearance, but it's a basic start for me to at least get the bar buttons working.
So If anyone needs this. Here is a BarButtonItem that works with this library in its current state. I'm still new to swift as I just came from Android development since our company is short-handed in the swift side. So there might be better ways to do this, but this works for me.
import UIKit
import FontAwesome_swift
@IBDesignable class FAIconBarButtonItem: UIBarButtonItem {
//MARK: - Variable Declearation
private let button = UIButton(type: .system)
@IBInspectable private var size: CGFloat = 15 {
didSet {
button.titleLabel?.font = UIFont.systemFont(ofSize: size)
setButtonIcon(icon: icon)
}
}
@IBInspectable private var text: String? = "Default" {
didSet {setButtonTitle(title: text)}
}
@IBInspectable private var normalColor: UIColor = .systemBlue {
didSet {
setButtonTitleColor(normalColor: normalColor)
setButtonIcon(icon: icon)
}
}
private var icon: FontAwesome = .powerOff {
didSet {setButtonIcon(icon: icon)}
}
@IBInspectable private var iconAdapter: String {
get {
return self.icon.rawValue
}
set(iconString) {
self.icon = FontAwesome(rawValue: iconString) ?? .powerOff
}
}
//Used to provide addTarget action
var touchUpInside: ((_ button: UIButton)->())?
//MARK: - Init
private override init(){
super.init()
target = self
customView = setup()
}
required init?(coder aDecorder: NSCoder) {
super.init(coder: aDecorder)
customView = setup()
}
//MARK: - Private Functions
private func setup() -> UIButton {
button.isEnabled = true
button.isUserInteractionEnabled = true
button.titleLabel?.font = UIFont.systemFont(ofSize: size)
setButtonTitleColor(normalColor: normalColor)
setButtonIcon(icon: icon)
setButtonTitle(title: text)
button.tintColor = normalColor
button.addTarget(self, action: #selector(touchUpInside(_:)), for: .touchUpInside)
button.sizeToFit()
return button
}
private func setButtonTitle(title: String?){
button.setTitle(title?.localized(), for: .normal)
}
private func setButtonTitleColor(normalColor: UIColor){
button.setTitleColor(normalColor, for: .normal)
}
private func setButtonIcon(icon: FontAwesome){
//All changes of icon, color, and size is made in this
let normalIconImage = UIImage.fontAwesomeIcon(name: icon, style: .solid, textColor: normalColor, size: CGSize(width: size, height: size))
button.tintColor = normalColor
button.setImage(normalIconImage, for: .normal)
}
@objc private func touchUpInside(_ sender: UIButton){
touchUpInside?(sender)
}
//MARK: - Exposed Functions
func setTitleAndIcon(title: String, icon: FontAwesome) {
setIcon(icon: icon)
setTitle(title: title)
}
func setTitle(title: String){
self.text = title
}
func setIcon(icon: FontAwesome){
self.icon = icon
}
func setColor(color: UIColor){
self.normalColor = color
}
}
Usage:
How to get button's action when pressed after linking your FABarButtonItem outlet In your ViewConroller
barButtonItem.touchUpInside = {
//whatever you want to do
//If you need other interaction methods, modify FABarButtonItem and use "touchUpInside" as an example.
}
//Change title
setTitle(title: String)
//Change icon
setIcon(icon: FontAwesome)
//Change title and icon
setTitleAndIcon(title: String, icon: FontAwesome)
//Change color
setColor(color: UIColor)
It should also work with code init but it's not in my use case so I didn't care, you can modify my code to get it working if it's not already.
Hi,
In my toolbar item, I have set everything according to the doc page, it was working fine because I was making my app in a different language than English. However, now my app requires English as an alternative language option and this problem occurred.
`let barItemFontAttr = [ NSAttributedString.Key.font: UIFont.fontAwesome(ofSize: 15, style: .solid) ]
refreshOrders.setTitleTextAttributes(barItemFontAttr, for: .normal) refreshOrders.setTitleTextAttributes(barItemFontAttr, for: .selected) refreshOrders.title = "(String.fontAwesomeIcon(name: .sync)) Sync" //Don't work refreshOrders.title = "(String.fontAwesomeIcon(name: .sync)) 同步" //Works`
Expected: Sync Icon + "Sync"
Got: Sync Icon + Sync Icon
How am I suppose to do this?