Finally iOS 8 and Xcode 6 are available and out of NDA and we can cover them on NSScreencast. There are tons of new features to cover, so today I'm just going to pick one: IBDesignable. With IBDesignable you can live preview your custom views so you don't have to stare at empty gray boxes in Interface Builder anymore. Interface Builder just got way more useful!
Small Correction: I stated in the video that you must use a framework to get IBDesignable classes to work in Storyboards/interface builder. This was true in earlier betas, but is no longer a requirement. Episode Links Episode Source Code IBDesignable Poster View @IBDesignable class PosterView : UIView { var label: UILabel! var imageView: UIImageView! @IBInspectable var text: NSString? { didSet { label.text = text } } @IBInspectable var image: UIImage? { didSet { imageView.image = image } } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) createSubviews() } override init(frame: CGRect) { super.init(frame: frame) createSubviews() } func createSubviews() { imageView = UIImageView() imageView.contentMode = UIViewContentMode.ScaleAspectFill addSubview(imageView) label = UILabel() label.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6) label.textColor = UIColor.whiteColor() label.font = UIFont.boldSystemFontOfSize(20) label.textAlignment = NSTextAlignment.Center addSubview(label) } override func layoutSubviews() { super.layoutSubviews() layer.borderWidth = 2.0 layer.borderColor = UIColor.blackColor().CGColor layer.cornerRadius = 24 clipsToBounds = true imageView.frame = self.bounds let labelHeight: CGFloat = 40 label.frame = CGRectMake(0, bounds.size.height - labelHeight, bounds.size.width, labelHeight) } override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() text = "Test Title" } } Adding in Assets that Aren't in Targets Often you'll want to show default assets on your controls without actually shipping them in your compiled application. To do this, add your assets to the project, but don't add them to any target. To refer to the image path at design-time (without resorting to hard-coded paths) do this: override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() let projectPaths = NSProcessInfo.processInfo().environment["IB_PROJECT_SOURCE_DIRECTORIES"].componentsSeparatedByString(",") if projectPaths.count > 0 { if let projectPath = projectPaths[0] as? String { let imagePath = projectPath.stringByAppendingPathComponent("TestImages/MyTestImage.jpg") image = UIImage(contentsOfFile: imagePath) // do something with image } } }