Skip to content

Instantly share code, notes, and snippets.

@algal
Last active February 2, 2016 12:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save algal/6a5ec13fdbba8943cb62 to your computer and use it in GitHub Desktop.
Save algal/6a5ec13fdbba8943cb62 to your computer and use it in GitHub Desktop.
Abstract UITableViewCell class for quickly defining UITableViewCell subclasses that merely wrap a custom UIView subclass
// ViewWrappingTableViewCell.swift
// Created by Alexis Gallagher on 6/4/15.
import UIKit
/**
Abstract superclass for quickly defining a `UITableViewCell` subclass that wraps a
specific `UIView` subclass. The resulting `UITableViewCell` will hug the wrapped view
with layout constraints, so that both the cell and the wrapped view can influence
each other's size via the normal Auto Layout mechanism.
To use, override the class function `wrappedViewType` and the computed property
`wrappedView`, like so:
class PersonView : UIView { /* etc */ }
class PersonTableViewCell : WrapperTableViewCell
{
override class func wrappedViewType() -> UIView.Type { return PersonView.self }
override var wrappedView:PersonView { return super.wrappedView as! PersonView }
}
(You might think this could be done with generics, so that `wrappedView` could be
defined with the wrapped type, but apparently not as of Swift 1.2.)
*/
class ViewWrappingTableViewCell : UITableViewCell
{
// override me!
class func wrappedViewType() -> UIView.Type {
fatalError("ERROR. Incomplete implementation. You must override the class function wrappedViewType to return the type of the view you are wrapping. You should also override the computed property wrappedView to return the wrappedView with the exact type. For instance, if you were wrapping PersonView:\n\n override class func wrappedViewType() -> UIView.Type { return PersonView.self }\n override var wrappedView:PersonView { return super.wrappedView as! PersonView }\n")
}
class var classReuseIdentifier:String {
return wrappedViewType().description() + "CellIdentifier"
}
override class func requiresConstraintBasedLayout() -> Bool { return true }
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifier)
setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
setup()
}
func setup()
{
self.selectionStyle = .None
let WrappedType = self.dynamicType.wrappedViewType()
let wrappedView = WrappedType(frame: self.contentView.bounds)
self.contentView.addSubview(wrappedView)
wrappedView.setTranslatesAutoresizingMaskIntoConstraints(false)
for vfl in ["V:|[v]|","H:|[v]|"]
{
let cs = NSLayoutConstraint.constraintsWithVisualFormat(vfl, options: .allZeros, metrics: nil, views: ["v":wrappedView]) as! [NSLayoutConstraint]
self.contentView.addConstraints(cs)
}
}
/** returns the wrapped view.
@discussion Implementors should override this to call the superclass property and return a more specific type.
*/
var wrappedView:UIView {
return self.contentView.subviews.first as! UIView
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment