I’d like to speak about liveness, it has been introduced in Xcode 6 and along with storyboard and interface preview is a great way to help you undestand how your application will look like without even launching on the simulator.
Watching the documentation I thought it was possible only by creating a subclass of UIView (or UIControl) programatically, while instead is possible to build our own UIView implementation and attach a xib file to it.
This is really helpful, for instance if you need to create a complex layout in a view building it with interface builder is a lot easier instead of coding each constraints.
How to do that?
1. Create a custom UIView subclass and a xib files, that we will name after our own class name: in our case MemeView. Inside the Meme View class remember to define it as designable, by adding the @IBDesignable attribute before the class declaration
2. Rember to set the File’s Owner in the xib with our custom UIView subclass in Indetity Inspector panel
3. In the xib file now we can build our interface, make constraints, create outlets, actions etc.
4. We need to implement few methods to our custom class to open the xib once initialized
weak var nibView: UIView! override convenience init(frame: CGRect) { let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last! self.init(nibName: nibName) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last! let nib = loadNib(nibName) nib.frame = bounds nib.translatesAutoresizingMaskIntoConstraints = false addSubview(nib) nibView = nib setUpConstraints() } init(nibName: String) { super.init(frame: CGRectZero) let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last! let nib = loadNib(nibName) nib.frame = bounds nib.translatesAutoresizingMaskIntoConstraints = false addSubview(nib) nibView = nib setUpConstraints() } func setUpConstraints() { ["V","H"].forEach { (quote) -> () in let format = String(format:"\(quote):|[nibView]|") addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(format, options: [], metrics: nil, views: ["nibView" : nibView])) } } func loadNib(name: String) -> UIView { let bundle = NSBundle(forClass: self.dynamicType) let nib = UINib(nibName: name, bundle: bundle) let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView return view }
5. In our custom class we can also define some inspectable properties to have full control over them from interface builder
@IBInspectable var memeImage: UIImage = UIImage() { didSet { imageView.image = memeImage } } @IBInspectable var textColor: UIColor = UIColor.whiteColor() { didSet { label.textColor = textColor } } @IBInspectable var text: String = "" { didSet { label.text = text } } @IBInspectable var roundedCorners: Bool = false { didSet { if roundedCorners { layer.cornerRadius = 20.0 clipsToBounds = true } else { layer.cornerRadius = 0.0 clipsToBounds = false } } } @IBOutlet weak var label: UILabel! @IBOutlet weak var imageView: UIImageView!
In this case swift property observers are super helpful in detect property changes and apply them in real time to out interface.
As a note is worth to mention that not all the types of variable can be inspected (CGPoint, CGSize, CGRect, UIColor, NSRange, UIImage and numbers), for instance if you try to make a font property inspectable it will fail silently and it will not be displayed inside the attribute inspector.
To abstract a little more the xib loading process I created a class subclass of UIView that already takes care of loading “a same class name” xib.
Here are the results.
If we need to fill with more information the view while it is displayed inside a storyboard or another xib, we can implement prepareForInterfaceBuilder(), this method will be executed only while opening the file in interface builder.
If you did everything I wrote but nothing is working, there is a way to debug a sigle view by adding breakpoints in its implementation.
You can download this little sample from dropbox.
The post Designable xib in Xcode? Hell yeah! appeared first on Cloud in Touch.