Skip to content

Instantly share code, notes, and snippets.

@neoneye
Created March 11, 2016 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neoneye/8f3b9755bad271572411 to your computer and use it in GitHub Desktop.
Save neoneye/8f3b9755bad271572411 to your computer and use it in GitHub Desktop.
I have just ported Paul Slot's awesome "PSCustomViewFromXib" from objective C to Swift
// Inspired by Paul Slot's awesome PSCustomViewFromXib, https://github.com/PaulSolt/CustomUIView
class CustomViewFromXib: UIView {
var customView: UIView?
override init(frame: CGRect) {
super.init(frame: frame)
let className = String(self.dynamicType)
let anyObjectOrNil: AnyObject? = NSBundle.mainBundle().loadNibNamed(className, owner: self, options: nil)?.first
guard let anyObject = anyObjectOrNil else {
print("ERROR: CustomViewFromXib.init(frame:) Expected customView to be non-nil, but got nil")
return
}
guard let customView = anyObject as? UIView else {
let classNameForAnyObject = String(anyObject.dynamicType)
print("ERROR: CustomViewFromXib.init(frame:) Expected customView to be a UIView, but got: \(classNameForAnyObject)")
return
}
self.customView = customView
customView.frame = self.bounds
if CGRectIsEmpty(frame) {
self.bounds = customView.bounds
}
addSubview(customView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
@PaulSolt
Copy link

Awesome!

@neoneye
Copy link
Author

neoneye commented May 11, 2017

Ported to Xcode8.3.1 and swift3.1

class CustomViewFromXib: UIView {
	var customView: UIView?
	
	override init(frame: CGRect) {
		super.init(frame: frame)
		
		let className = String(describing: type(of: self))
		let topLevelObjects: [Any]? = Bundle.main.loadNibNamed(className, owner: self, options: nil)
		guard let topLevelObject = topLevelObjects?.first else {
			print("ERROR: CustomViewFromXib.init(frame:) Expected topLevelObject to be non-nil, but got nil")
			return
		}
		
		guard let customView = topLevelObject as? UIView else {
			let classNameForTopLevelObject = String(describing: type(of: topLevelObject))
			print("ERROR: CustomViewFromXib.init(frame:) Expected customView to be a UIView, but got: \(classNameForTopLevelObject)")
			return
		}
		self.customView = customView
		customView.frame = self.bounds
		
		if frame.isEmpty {
			self.bounds = customView.bounds
		}
		
		addSubview(customView)
	}
	
	required init?(coder aDecoder: NSCoder) {
		fatalError("init(coder:) has not been implemented")
	}
}

@neoneye
Copy link
Author

neoneye commented May 11, 2017

class CustomViewFromXib: UIView {
	var customView: UIView?
	
	override init(frame: CGRect) {
		super.init(frame: frame)
		
		let nibName = String(describing: type(of: self))
		let customView: UIView = Bundle.loadView(fromNib: nibName, withType: UIView.self)
		self.customView = customView
		customView.frame = self.bounds
		
		if frame.isEmpty {
			self.bounds = customView.bounds
		}
		
		addSubview(customView)
	}
	
	required init?(coder aDecoder: NSCoder) {
		fatalError("init(coder:) has not been implemented")
	}
}

extension Bundle {
	static func loadView<T>(fromNib name: String, withType typeId: T.Type) -> T {
		guard let view = Bundle.main.loadNibNamed(name, owner: nil, options: nil)?.first as? T else {
			fatalError("Could not load view with type \(type(of: typeId))")
		}
		return view
	}
}

@PaulSolt
Copy link

Is this something that you could create a pull-request and wrap up into: CustomUIView with a Swift version of the project?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment