         case Spring(bounce: CGFloat, speed: CGFloat)
         case Custom(POPPropertyAnimation)
     }
-    
-    // MARK: - Views
-    
-    /// Alert title label.
-    lazy var titleText: UILabel = {
-        let label = UILabel()
-        label.textAlignment = .center
-        label.translatesAutoresizingMaskIntoConstraints = false
-        return label
-    }()
-    
-    /// Alert message label.
-    lazy var messageLabel: UILabel = {
-        let label = UILabel()
-        label.textAlignment = .center
-        label.translatesAutoresizingMaskIntoConstraints = false
-        return label
-    }()
     
     // MARK: - Defaults
     

        }
        DispatchQueue.main.async {
            let dismissAnimation = POPBasicAnimation(propertyNamed: kPOPLayoutConstraintConstant)
            dismissAnimation?.toValue = -Defaults.Height
            dismissAnimation?.duration = Defaults.AnimationDuration
            animatedConstraint.pop_add(dismissAnimation, forKey: "dropdown-dismiss")
            DispatchQueue.main.asyncAfter(deadline: .now() + Defaults.AnimationDuration) {

        self.commonInit()
    }
    
    func commonInit() {
        
        self.addTarget(self, action: #selector(CRDropdownAlert.viewWasTapped(alertView:)), for: .touchUpInside);
        
        NotificationCenter.default.addObserver(self, selector: #selector(CRDropdownAlert.dismiss), name: NSNotification.Name(rawValue: CRDropdownAlert.CRDropdownAlertDismissAllNotification), object: nil);
    }
    
    fileprivate func addToWindow(_ window :UIWindow) {
        
        // Construct a padding view that will cover the top of the dropdown in the case of a spring animation where it bounces past its bounds
        let paddingView = UIView()
        paddingView.backgroundColor = backgroundColor
        paddingView.translatesAutoresizingMaskIntoConstraints = false
        
        window.addSubview(self)
        window.addSubview(paddingView)
        
        // Add the drop downconstraint
        window.addConstraint(NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: window, attribute: .left, multiplier: 1, constant: 0))
        window.addConstraint(NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: window, attribute: .right, multiplier: 1, constant: 0))
        window.addConstraint(NSLayoutConstraint(item: self, attribute: .height, relatedBy: .greaterThanOrEqual, toItem: nil, attribute: .height, multiplier: 1, constant: self.getHeight()))
        
        // Add the padding view constraints
        window.addConstraint(NSLayoutConstraint(item: paddingView, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1, constant: 0))
        window.addConstraint(NSLayoutConstraint(item: paddingView, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1, constant: 0))
        window.addConstraint(NSLayoutConstraint(item: paddingView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        window.addConstraint(NSLayoutConstraint(item: paddingView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0))
    }
    
    @objc
    private func viewWasTapped(alertView :UIView) {
        
        if let delegate = self.delegate {
            if delegate.dropdownAlertWasTapped(alert: self) {
                self.dismiss();
            }
        } else {
            self.dismiss();
        }
    }
    
    fileprivate func getHeight() -> CGFloat {
        assert(false, "Subclasses need to override getHeight");
    }
    
}

private class CRTextDropdownAlert : CRDropdownAlert {
    
    /// Alert title label.
    lazy var titleText: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    /// Alert message label.
    lazy var messageLabel: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    public convenience init(title :String, message :String, backgroundColor :UIColor, textColor :UIColor, delegate :CRDropdownAlertDelegate?) {
        
        self.init();
        self.translatesAutoresizingMaskIntoConstraints = false
        
        self.delegate = delegate;
        
        self.titleText.text = title
        self.messageLabel.text = message
        self.titleText.textColor = textColor
        self.messageLabel.textColor = textColor
        self.messageLabel.numberOfLines = 0
        self.backgroundColor = backgroundColor
    }
    
    override func commonInit() {
        super.commonInit();
        
        self.titleText.font = Defaults.TitleFont
        self.messageLabel.font = Defaults.MessageFont
        
        self.addSubview(self.titleText)
        self.addSubview(self.messageLabel)
        
        self.setupConstraints()
    }
    
    /**
     Setup the constraints for the dropdown's labels.
     */
    private func setupConstraints() {
        
        self.addConstraint(NSLayoutConstraint(item: self.titleText, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: self.titleText, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: self.titleText, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.95, constant: 0))
        
        self.addConstraint(NSLayoutConstraint(item: self.messageLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: self.messageLabel, attribute: .top, relatedBy: .equal, toItem: self.titleText, attribute: .bottom, multiplier: 1, constant: Defaults.MiddlePadding))
        self.addConstraint(NSLayoutConstraint(item: self.messageLabel, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: -Defaults.BottomPadding))
        self.addConstraint(NSLayoutConstraint(item: self.messageLabel, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.95, constant: 0))
        
        self.layoutIfNeeded()
    }
    
    fileprivate override func getHeight() -> CGFloat {
        
        let titleFrame = self.titleText.frame;
        let titleHeight = titleFrame.size.height;
        let messageFrame = self.messageLabel.frame;
        let messageHeight = messageFrame.size.height;
        
        return Defaults.TopPadding + titleHeight + Defaults.MiddlePadding + messageHeight + Defaults.BottomPadding;
    }
}

private class CRCustomDropdownAlert : CRDropdownAlert {
    
    private var contentView :UIView? = nil;
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    public convenience init(view :UIView, backgroundColor :UIColor, delegate :CRDropdownAlertDelegate?) {
        
        self.init();
        self.translatesAutoresizingMaskIntoConstraints = false
        
        self.delegate = delegate;
        self.contentView = view;
        
        self.addSubview(view);
        self.backgroundColor = backgroundColor;
        
        setupConstraints(view: view);
    }
    
    private func setupConstraints(view :UIView) {
        
        view.translatesAutoresizingMaskIntoConstraints = false
        
        self.addConstraint(NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: -Defaults.BottomPadding));
        self.addConstraint(NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.95, constant: 0));
        self.addConstraint(NSLayoutConstraint(item: view, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        
        self.layoutIfNeeded();
    }
    
    override func getHeight() -> CGFloat {
        
        if let contentView = self.contentView {
            let frame = contentView.frame;
            return Defaults.TopPadding + contentView.frame.size.height + Defaults.BottomPadding;
        }
        
        return 0;
    }
    
}

public extension CRDropdownAlert {
