In my previous post Xcode 6 Live Rendering From Nib, we ended up with CustomView a UIView subclass backed by a nib that is supported by Xcode Live Rendering.

import UIKit @ IBDesignable class CustomView : UIView { @ IBOutlet weak var avatarImageView : UIImageView ! @ IBOutlet weak var titleLabel : UILabel ! private weak var proxyView : CustomView ? @ IBInspectable public var title : String = "" { didSet { self . proxyView ! . titleLabel . text = title } } @ IBInspectable public var avatarImage : UIImage = UIImage () { didSet { let size = self . avatarImage . size let rect = CGRectMake ( 0 , 0 , size . width , size . height ) UIGraphicsBeginImageContextWithOptions ( size , false , 0.0 ) var path = UIBezierPath ( ovalInRect : rect ) path . addClip () self . avatarImage . drawInRect ( rect ) let image = UIGraphicsGetImageFromCurrentImageContext () UIGraphicsEndImageContext () self . proxyView ! . avatarImageView . image = image } } init ( frame : CGRect ) { super . init ( frame : frame ) var view = self . loadNib () view . frame = self . bounds view . autoresizingMask = . FlexibleWidth | . FlexibleHeight self . proxyView = view self . addSubview ( self . proxyView ) } init ( coder aDecoder : NSCoder ! ) { super . init ( coder : aDecoder ) } override func awakeAfterUsingCoder ( aDecoder : NSCoder ! ) -> AnyObject ! { if self . subviews . count == 0 { var view = self . loadNib () view . setTranslatesAutoresizingMaskIntoConstraints ( false ) let contraints = self . constraints () self . removeConstraints ( contraints ) view . addConstraints ( contraints ) view . proxyView = view return view } return self } private func loadNib () -> CustomView { let bundle = NSBundle ( forClass : self . dynamicType ) return bundle . loadNibNamed ( "CustomView" , owner : nil , options : nil )[ 0 ] as CustomView } }

This works well for a single custom view, but who only got one custom view, so let me introduce Nib Designable.

Nib Designable is a single file which enables Live Rendering on its subclass’.

import UIKit @ IBDesignable public class NibDesignable : UIView { // MARK: - Initializer override init ( frame : CGRect ) { super . init ( frame : frame ) self . setupNib () } // MARK: - NSCoding required public init ( coder aDecoder : NSCoder ! ) { super . init ( coder : aDecoder ) self . setupNib () } // MARK: - Nib loading /** Called in init(frame:) and init(aDecoder:) to load the nib and add it as a subview. */ private func setupNib () { var view = self . loadNib () view . frame = self . bounds view . autoresizingMask = . FlexibleWidth | . FlexibleHeight self . addSubview ( view ) } /** Called to load the nib in setupNib(). :returns: UIView instance loaded from a nib file. */ public func loadNib () -> UIView { let bundle = NSBundle ( forClass : self . dynamicType ) return bundle . loadNibNamed ( self . nibName (), owner : self , options : nil )[ 0 ] as UIView } /** Called in the default implementation of loadNib(). Default is class name. :returns: Name of a single view nib file. */ public func nibName () -> String { return self . dynamicType . description (). componentsSeparatedByString ( "." ). last ! } }

NibDesignable is almost identical to CustomView from my previous post.

I added nibName() -> String to ease the usage.

For more details on Nib Designable, head over to the Github repository.