Swift subclass UIView
I usually do something like this, its a bit verbose.
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
addBehavior()
}
convenience init() {
self.init(frame: CGRect.zero)
}
required init(coder aDecoder: NSCoder) {
fatalError("This class does not support NSCoding")
}
func addBehavior() {
print("Add all the behavior here")
}
}
let u = MyView(frame: CGRect.zero)
let v = MyView()
(Edit: I've edited my answer so that the relation between the initializers is more clear)
What is the steps to create a subclass for UIView that adds border?]
There's a pretty detailed answer here:
Proper practice for subclassing UIView?
Basically, you should override:
init?(coder aDecoder: NSCoder)
and init(frame: CGRect)
as well as awakeFromNib()
. Just call another function from there where you set the border.
How to properly init passed property in subclass of UIView?
If you want to initialize a UIView
with a custom property you must reconfigure its initializer:
class InputWithIncrementView: UIView {
let inputName: String
init(inputName: String) {
self.inputName = inputName
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) {
return nil
}
}
Subclassing a UIView
Think about what you expect to happen in…
override init(frame: CGRect) {
super.init(frame: frame)
alertLayout()
}
and
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
alertLayout()
}
You have a non-optional instance variable title
. How is it supposed to get a value in these 2 cases?
And in your 3rd init
…
convenience init(title: String) {
self.title = title
self.init(title: title)
}
init(title: String)
calls init(title: String)
, which in turn calls init(title: String)
, etc. You're in infinite recursion territory.
If you want to instantiate the view in code, you'll need something like…
init(title: String, frame: CGRect) {
self.title = title
super.init(frame: frame)
alertLayout()
}
and you'll also need to implement
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
If you're using this in a storyboard / nib, then you'll need…
required init?(coder aDecoder: NSCoder) {
self.title = ""
super.init(coder: aDecoder)
}
and then assign a value to title
afterwards
accessing UIView subclass in view controller
Posting my own answer.
- Create the XIB file.
- Create the UIView subclass Swift file.
- Under the XIB file owner's Identify Inspector custom class field, type in the UIView subclass name (your custom view).
- Under the XIB file owner's Connections Inspector, make sure all IBOutlets in the Swift file are connected.
- Add a view to the view controller and under its Identify Inspector custom class type, specify the custom class name.
Important:
* In your XIB swift file, you have to properly load the XIB content view.
...
/// Initializer used by Interface Builder.
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
/// Initializer used programmatically.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
...
func configure() {
let contentView = // here use many of the functions available on the internet to
// load a view from a nib.
// Then add this view to the view hierarchy.
addSubview(contentView)
}
How do I write a custom init for a UIView subclass in Swift?
The init(frame:)
version is the default initializer. You must call it only after initializing your instance variables. If this view is being reconstituted from a Nib then your custom initializer will not be called, and instead the init?(coder:)
version will be called. Since Swift now requires an implementation of the required init?(coder:)
, I have updated the example below and changed the let
variable declarations to var
and optional. In this case, you would initialize them in awakeFromNib()
or at some later time.
class TestView : UIView {
var s: String?
var i: Int?
init(s: String, i: Int) {
self.s = s
self.i = i
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Swift UIView subclass with auto layout
Why are you giving the label heightAnchor?
If you want it to be automatically resized depends on the text all you to do is:
- numberOfLines is 0 for the label
- give top,leading,bottom and trailing anchors for the label to its super view
- super view should at least has top,leading and trailing anchors to its super view (View controller view) where you are going to add this custom view.
DONT forget while init the custom view set the property translatesAutoresizingMaskIntoConstraints to false
Use @IBInspectable with any UIView subclass within storyboards
Move your code to UIView's @IBDesignable extension
like below:
@IBDesignable extension UIView {
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
layer.masksToBounds = true
}
get {
return self.cornerRadius
}
}
}
Clear unwanted values/types of previously deifned vars in your GEView
. Here are values in inspector.
Properties available in inspector of any UIView, included itself.
How to get a UIView subclass instance from its ViewController in Swift
I've just put this quick example together, Notice in the screenshot that the IBOutlet has a type of CustomView.
What I done was to add the UIView in the storyboard and then change the class in the property inspector to CustomView and THEN created the IBOutlet. This then used the correct type, so I could reference the custom properties and functions of the view.
You can update the type in your outlet if you created it before as long as it matches up with the class in the property inspector.
Related Topics
How to Pop Two Views at Once from a Navigation Controller
Saving PDF Files with Swift in iOS and Display Them
Align Text Using Drawinrect:Withattributes:
Invalid Update: Invalid Number of Items on Uicollectionview
Uiscrollview Adjusts Contentoffset When Contentsize Changes
How to Set Fake Gps Location on iOS Real Device
Avaudiosession Setcategory Swift 4.2 iOS 12 - Play Sound on Silent
Delay/Wait in a Test Case of Xcode UI Testing
How to Change Height of Grouped Uitableview Header
Find Where Object Is Retained with Arc
Accessing Core Data SQL Database in iOS 8 Extension (Sharing Data Between App and Widget Extension)
Facebook Share Content Only Shares Url in iOS 9
How to Convert .Dae to .Scn Files in Scenekit
How to Get the Custom Overlay for Uiimagepicker Camera to Be Full Screen in iOS 7