ExpandingMenu
ExpandingMenu copied to clipboard
Add support for Autolyout
It would be great if you could add support for Autolayout.
Currently I'm trying something like this, but it is not working with conditions you have made inside your code.
private func configureAutolayoutConstraints(buttonView: UIView, parentView: UIView){
buttonView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = NSLayoutConstraint(item: buttonView, attribute:
.Bottom, relatedBy: .Equal, toItem: parentView, attribute: .Bottom, multiplier: 1.0, constant: -30)
parentView.addConstraint(bottomConstraint)
let trailingConstraint = NSLayoutConstraint(item: buttonView, attribute:
.Trailing, relatedBy: .Equal, toItem: parentView, attribute: .Trailing, multiplier: 1.0, constant: -30)
parentView.addConstraint(trailingConstraint)
let widthConstraint = NSLayoutConstraint(item: buttonView, attribute:
.Width , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 80)
parentView.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: buttonView, attribute:
.Height , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 80)
parentView.addConstraint(heightConstraint)
}
Perhaps my adoption (very basic) is a starting point:
class SocialButton: NSObject {
private weak var parentController : UIViewController?
private var dimmedView : UIView?
private var mainButton : UIButton?
private var menuButtons = [SocialMenuButton]()
private var menuIsVisible = false
var dimmedViewTopConstraint: NSLayoutConstraint?
var dimmedViewBottomConstraint: NSLayoutConstraint?
var dimmedViewTrailingConstraint: NSLayoutConstraint?
var dimmedViewLeadingConstraint: NSLayoutConstraint?
func configureSocialButtonForViewController(controller: UIViewController) {
self.parentController = controller
self.addDimmedView(controller.view)
self.addButtonView(controller.view)
self.addMenuItems(self.parentController!.view)
self.parentController?.view.layoutIfNeeded()
self.parentController?.view.bringSubviewToFront(mainButton!)
}
func addMenuItems(parentView: UIView){
let socialMenuButton1 = SocialMenuButton(parentView: parentView, referenceView: mainButton!, index: 0, title: "Menu1", image: UIImage(named: "logo")!, highlightedImage: UIImage(named: "logo")!) { () -> Void in
self.showAlert("Menu1")
self.mainButtonTapped()
}
self.menuButtons.append(socialMenuButton1)
let socialMenuButton2 = SocialMenuButton(parentView: parentView, referenceView: mainButton!, index: 1, title: "Menu2", image: UIImage(named: "logo")!, highlightedImage: UIImage(named: "logo")!) { () -> Void in
self.showAlert("Menu2")
self.mainButtonTapped()
}
self.menuButtons.append(socialMenuButton2)
let socialMenuButton3 = SocialMenuButton(parentView: parentView, referenceView: mainButton!, index: 2, title: "Menu3", image: UIImage(named: "logo")!, highlightedImage: UIImage(named: "logo")!) { () -> Void in
self.showAlert("Menu3")
self.mainButtonTapped()
}
self.menuButtons.append(socialMenuButton3)
let socialMenuButton4 = SocialMenuButton(parentView: parentView, referenceView: mainButton!, index: 3, title: "Menu4", image: UIImage(named: "logo")!, highlightedImage: UIImage(named: "logo")!) { () -> Void in
self.showAlert("Menu4")
self.mainButtonTapped()
}
self.menuButtons.append(socialMenuButton4)
}
func hideMenuItems(){
for item in menuButtons{
item.hideItem()
}
}
func showAlert(title: String) {
let alert = UIAlertController(title: title, message: nil, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
self.parentController?.presentViewController(alert, animated: true, completion: nil)
}
func addDimmedView(parentView: UIView){
dimmedView = UIView(frame: CGRect(x: 0,y: 0,width: 10,height: 10))
if let dimmedView = self.dimmedView{
dimmedView.backgroundColor = UIColor.darkGrayColor()
let tap = UITapGestureRecognizer(target: self, action: Selector("mainButtonTapped"))
dimmedView.addGestureRecognizer(tap)
dimmedView.userInteractionEnabled = true
parentView.addSubview(dimmedView)
//Configure autolayout
dimmedView.translatesAutoresizingMaskIntoConstraints = false
let y = UIScreen.mainScreen().bounds.size.height
let x = UIScreen.mainScreen().bounds.size.width
dimmedViewTopConstraint = NSLayoutConstraint(item: dimmedView, attribute:
.Top , relatedBy: .Equal, toItem: parentView, attribute: .Top, multiplier: 1.0, constant: y)
parentView.addConstraint(dimmedViewTopConstraint!)
dimmedViewBottomConstraint = NSLayoutConstraint(item: dimmedView, attribute:
.Bottom , relatedBy: .Equal, toItem: parentView, attribute: .Bottom, multiplier: 1.0, constant: 0)
parentView.addConstraint(dimmedViewBottomConstraint!)
dimmedViewTrailingConstraint = NSLayoutConstraint(item: dimmedView, attribute:
.Trailing , relatedBy: .Equal, toItem: parentView, attribute: .Trailing, multiplier: 1.0, constant: 0)
parentView.addConstraint(dimmedViewTrailingConstraint!)
dimmedViewLeadingConstraint = NSLayoutConstraint(item: dimmedView, attribute:
.Leading , relatedBy: .Equal, toItem: parentView, attribute: .Leading, multiplier: 1.0, constant: x)
parentView.addConstraint(dimmedViewLeadingConstraint!)
}
}
func addButtonView(parentView: UIView){
mainButton = UIButton(frame: CGRect(x:0, y:0, width: 60, height: 60))
if let mainButton = self.mainButton{
mainButton.setImage(UIImage(named: "chooser-button-tab"), forState: UIControlState.Normal)
mainButton.setImage(UIImage(named: "chooser-button-tab-highlighted"), forState: UIControlState.Highlighted)
mainButton.addTarget(self, action: "mainButtonTapped", forControlEvents: UIControlEvents.TouchUpInside)
//mainButton.backgroundColor = UIColor.blueColor()
parentView.addSubview(mainButton)
//Configure autolayout
mainButton.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = NSLayoutConstraint(item: mainButton, attribute:
.Bottom, relatedBy: .Equal, toItem: parentView, attribute: .Bottom, multiplier: 1.0, constant: -50)
parentView.addConstraint(bottomConstraint)
let trailingConstraint = NSLayoutConstraint(item: mainButton, attribute:
.Trailing, relatedBy: .Equal, toItem: parentView, attribute: .Trailing, multiplier: 1.0, constant: 0)
parentView.addConstraint(trailingConstraint)
let widthConstraint = NSLayoutConstraint(item: mainButton, attribute:
.Width , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60)
parentView.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: mainButton, attribute:
.Height , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60)
parentView.addConstraint(heightConstraint)
}
}
func mainButtonTapped(){
if self.menuIsVisible{
//hide
self.hideMenuItems()
self.menuIsVisible = !self.menuIsVisible
self.dimmedView?.alpha = 0.0
self.dimmedViewTopConstraint?.constant = (self.mainButton?.frame.origin.y)!
self.dimmedViewLeadingConstraint?.constant = (self.mainButton?.frame.origin.x)!
self.parentController?.view.layoutIfNeeded()
}
else{
//show
self.dimmedView?.alpha = 0.7
self.dimmedViewTopConstraint?.constant = 0
self.dimmedViewLeadingConstraint?.constant = 0
self.parentController?.view.layoutIfNeeded()
UIView.animateWithDuration(0.3, animations: { () -> Void in
for item in self.menuButtons{
item.showItem()
self.parentController?.view.layoutIfNeeded()
}
}, completion: { (finished) -> Void in
self.menuIsVisible = !self.menuIsVisible
})
}
}
// MARK: - Menu Item Tapped Action
func menuItemTapped(item: SocialMenuButton) {
mainButtonTapped()
}
}
class SocialMenuButton: UIView {
private var menuButton : UIButton?
private var textLabel : UILabel?
weak private var delegate: SocialButton?
private var tappedAction: (() -> Void)?
private var bottomConstraint: NSLayoutConstraint?
private var index = 0
init(parentView: UIView, referenceView: UIView, index: Int, title: String, image: UIImage, highlightedImage: UIImage, itemTapped: (() -> Void)?) {
let itemFrame = CGRect(x: 0.0, y: 0.0, width: image.size.width, height: image.size.height)
super.init(frame: itemFrame)
self.index = index
addButton(parentView, referenceView: referenceView, index: index, image: image, highlightedImage: highlightedImage, itemTapped: itemTapped)
addTextLabel(parentView, title: title)
self.tappedAction = itemTapped
self.hideItem()
}
private func addButton(parentView: UIView, referenceView: UIView, index: Int, image: UIImage, highlightedImage: UIImage, itemTapped: (() -> Void)?){
menuButton = UIButton(frame: CGRect(x:0, y:0, width: 30, height: 30))
if let menuButton = menuButton {
menuButton.setImage(image , forState: UIControlState.Normal)
menuButton.setImage(highlightedImage , forState: UIControlState.Highlighted)
menuButton.addTarget(self, action: "tapped", forControlEvents: UIControlEvents.TouchUpInside)
//menuButton.backgroundColor = UIColor.greenColor()
parentView.addSubview(menuButton)
menuButton.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = NSLayoutConstraint(item: menuButton, attribute:
.Width , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 45)
parentView.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: menuButton, attribute:
.Height , relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 45)
parentView.addConstraint(heightConstraint)
bottomConstraint = NSLayoutConstraint(item: menuButton, attribute:
.Bottom, relatedBy: .Equal, toItem: referenceView, attribute: .Top, multiplier: 1.0, constant:menuButton.bounds.height )
parentView.addConstraint(bottomConstraint!)
let trailingConstraint = NSLayoutConstraint(item: menuButton, attribute:
.Trailing, relatedBy: .Equal, toItem: referenceView, attribute: .Trailing, multiplier: 1.0, constant: -10)
parentView.addConstraint(trailingConstraint)
}
}
private func addTextLabel(parentView: UIView, title: String){
textLabel = UILabel(frame: CGRect(x:0, y:0, width: 100, height: 30))
if let textLabel = textLabel{
textLabel.text = title
//textLabel.backgroundColor = UIColor.greenColor()
textLabel.font = UIFont.systemFontOfSize(22)
textLabel.textColor = UIColor.whiteColor()
let tap = UITapGestureRecognizer(target: self, action: Selector("tapped"))
textLabel.addGestureRecognizer(tap)
textLabel.userInteractionEnabled = true
parentView.addSubview(textLabel)
textLabel.translatesAutoresizingMaskIntoConstraints = false
let trailingConstraint = NSLayoutConstraint(item: textLabel, attribute:
.Trailing, relatedBy: .Equal, toItem: menuButton, attribute: .Leading, multiplier: 1.0, constant: -20)
parentView.addConstraint(trailingConstraint)
let centerYConstraint = NSLayoutConstraint(item: textLabel, attribute:
.CenterY, relatedBy: .Equal, toItem: menuButton, attribute: .CenterY, multiplier: 1.0, constant: 0)
parentView.addConstraint(centerYConstraint)
}
}
func showItem(){
bottomConstraint?.constant = CGFloat(self.index) * -60
self.alpha = 1.0
self.menuButton?.alpha = 1.0
self.textLabel?.alpha = 1.0
}
func hideItem(){
self.alpha = 0.0
self.menuButton?.alpha = 0.0
self.textLabel?.alpha = 0.0
bottomConstraint?.constant = (menuButton?.bounds.height)!
}
func removeSubviews(){
self.textLabel?.removeFromSuperview()
self.menuButton?.removeFromSuperview()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
// MARK: - Tapped Action
func tapped() {
self.delegate?.menuItemTapped(self)
self.tappedAction?()
}
}
+1
Totally agree, without the auto-layout support the https://github.com/monoqlo/ExpandingMenu/issues/6 becomes a real issue and makes this nice library not usable in production without hacks.