Change font of labels with #IBDesignable - ios

This is a class that is supposed to change the font of a label dynamically, right in the Storyboard:
#IBDesignable class FlexibleLabel: UILabel {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.font = UIFont(name: "Brandon Grotesque", size: self.font.pointSize)
}
}
I assigned this class to some labels but I get this error:
Failed to update auto layout status: The agent crashed.
What can I do to fix this?

The first method which is called after the view is fully initialized from nib is UIView's awakeFromNib() method. You can override and use it to modify view's or subviews properties

To figure out why the agent crashed, select the FlexibleLabel instance in your storyboard and from the menu bar choose Editor > Debug Selected Views. If the problem is in your code, Xcode should put you in the debugger at the crash.
Xcode doesn't use init(coder:) to create views when editing a storyboard. It uses init(frame:), then sets the properties of the view using KVC (key-value coding).

Related

iOS custom UIView has different layout in iphone xr and iphone 7

I got auto-layout issue with custom UIView which render correctly in iphone XR
as
but wrong in iphone 7s(the "Reset" button is rendered out of bound)
and setting in storyboard with just a viewcontroller(UI), and no specified UIViewController class, for simplification i just want to debug the view so i do not associate any viewcontroller class to it.
p.s Safe-area has been used
and the custom class UI(FilterView) setting:
and the custom class UI(FilterView) code:
override init(frame: CGRect){
super.init(frame: frame)
setUpView()
}
//for IB
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpView()
}
private func setUpView(){
Bundle.main.loadNibNamed(Constants.NIB_FILTER_VIEW_NAME, owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
contentView.autoresizingMask = []
contentView.translatesAutoresizingMaskIntoConstraints = true
}
Anyone knows what happened here?
You should not be creating the X button and "Sort by" label that way. What you are doing is replicating what a UINavigationController does. If you want that layout then put your view controller inside a UINavigationController and it will make it much much easier to add the X and the "Sort by" label.
Also by doing this you can add a rightBarItem to be your "reset" button. Again, you don't have to lay this out. UINavigationController does all that for you.

Separator color in custom UITableView doesn't change

I have navigation controller and every VC has customTableView. In my customTableView I put UI settings inside init() method like this:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
separatorColor = UIColor.orange
}
but it doesn't work. But any other parameters of tableView like backgroundColor, sectionIndexColor and others work well. So I got problem only with separator color. Just to say, all my views and cells have clearColor.
If I put this code in view controller (that has an outlet of my customTableView) inside viewDidLoad method - then it works. What I'm trying to achieve is to have only one subclassed UITableView class with predefined parameters to use in every VC in my navigation stacks.
So, I found a way to make it work. I just override separatorColor property in my customTableView class like this:
override var separatorColor: UIColor? {
get {
return UIColor.orange
}
set {
super.separatorColor = newValue
}
}
But I still cannot realise why this property cannot be set like others inside init() method.
There are at least two initializers that may be called:
1. required init?(coder aDecoder: NSCoder)
this initializer will be called when view will be initialized from Interface Builder (.xib or .storyboard). To initialize view from IB set the class of some view or subview to the view class you are using.
2. plain init()
will be called when you will initialize your view from code. There may be variation of this initializer, like init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) for UITableViewCell and so on.
So make sure if you are using right initializer. At least you can set breakpoint to see if this init is called or not.
Hope it helps!

Manipulate IB Outlets in awakeFromNib for UICollectionViewCell even if not using custom XIB?

The code below is used to manipulate and configure IB Outlets of a subclassed UICollectionViewCell.
The IB outlets in the class, however, are not yet connected at this stage.
Other SO posts like this one suggest using awakeFromNib to manipulate the IB outlets, but in all the answers, the problem deals with a custom XIB.
However, this subclass doesn't use a custom XIB.
Is it still right to use awakeFromNib to configure the IB outlets even if no custom XIB is used?
override init(frame: CGRect) {
super.init(frame: frame)
doInit(frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
doInit(frame)
}
private func doInit(frame: CGRect) {
}

How to create a style or theme on swift so I can set color to all UITextField

It seems to be pretty obvious but I couldn't find much about it after hours.
I'm build an App on swift 2.0 and I have a dark background to all views.
I want to set a common background and color to all my text views, people recommend that each view should set the properties on viewDidLoad, but I don't want to set to each textView one by one the same information. It will be a hell to maintain.
Any hints?
Technically yes, each one should be done separately so that you have more control over things. However, if you want to change the background color of all of your text fields you can do it like this:
UITextField.appearance().backgroundColor = //Your color
You can also change the caret color using this:
UITextField.appearance().tintColor = //Your color
If you want to change these colors for a UITextView then simply swap UITextField.appearance()... for UITextView.appearance()...
Subclass UITextView and set the properties to what you desire in the init method. Then have each of your UITextView have a Custom Class set to your UITextView subclass.
Example:
class UITextViewSubclass: UITextView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.whiteColor()
}
}
With this approach, you could also declare some #IBInspectable properties which means they can be modified from the Inspector, if you want to change this color from the Inspector instead of changes inside your code.
class UITextViewSubclass: UITextView {
#IBInspectable var customBackgroundColor: UIColor = UIColor.whiteColor() {
didSet {
backgroundColor = customBackgroundColor
}
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = customBackgroundColor
}
}
One approach is to use UIAppearance with to change all UITextView, or you can subclass UITextView and modify the object after initialisation, then use that subclass instead of UITextView.

How to load xib to UIView subclass, Swift, iOS

I have a .xib file called ContentView that I want to use as the view for a class called ContentView, however I cannot seem to load it.
class ContentView: UIView {
override init() {
super.init(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
fatalError("init(coder:) has not been implemented")
}
}
I'm aware that you can load a xib using the following method but this gives a error when I do so:
var contentViewXib: NSArray = NSBundle.mainBundle().loadNibNamed("ContentView", owner: nil, options: nil)
I have also set the xibs files owner to ContentView and set its Custom Class in interface builder to the class I want to use it with.
Any help is appreciated. Thanks
If you set File's owner to ContentView, then view in your XIB is not ContentView, it is normal UIView that ContentView can retrieve.
In the init method of ContentView, call NSBundle.mainBundle().loadNibNamed() just like you wrote in your question and then type:
self.addSubview(contentViewXib[0])
You will also need to set constraints or autoresizing mask for this new view.
EDIT:
Another solution is to select view directly (not File's Owner) and change its class to ContentView.

Resources