Reputation: 65
I am trying to create a View Controller entirely programmatically to use it as a slide-out menu to be accessed from any scene in my app. There are many other VCs in the app that use storyboard (one day I'll be able to remove storyboard altogether I hope). My code is like this:
import UIKit
class MenuViewController: UIViewController {
var stkMenu: UIStackView {
let s = UIStackView(frame: view.frame)
s.axis = .vertical
s.distribution = .fillEqually
s.alignment = .fill
s.translatesAutoresizingMaskIntoConstraints = false
return s
}
var butSettings: UIButton = {
let b = UIButton()
b.backgroundColor = UIColor.clear
b.setTitle("SETTINGS", for: .normal)
b.showsTouchWhenHighlighted = true
b.titleLabel?.font = UIFont(name: "Roboto-Bold", size: 20)
b.setTitleColor(UIColor.netScoreGreen(), for: .normal)
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
var butAbout: UIButton = {
let b = UIButton()
b.backgroundColor = UIColor.clear
b.setTitle("ABOUT", for: .normal)
b.showsTouchWhenHighlighted = true
b.titleLabel?.font = UIFont(name: "Roboto-Bold", size: 20)
b.setTitleColor(UIColor.netScoreGreen(), for: .normal)
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
stkMenu.addArrangedSubview(butSettings)
stkMenu.addArrangedSubview(butAbout)
view.addSubview(stkMenu)
view.translatesAutoresizingMaskIntoConstraints = false
let swipe = UISwipeGestureRecognizer(target: self.view, action: #selector(dismissVC))
self.view.addGestureRecognizer(swipe)
swipe.direction = .right
swipe.isEnabled = true
// NSLayoutConstraint.activate([
// stkMenu.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
// stkMenu.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50),
// stkMenu.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
// stkMenu.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)
// ])
view.layoutIfNeeded()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func dismissVC() {
self.dismiss(animated: true, completion: nil)
}
}
Pretty much everything I try with this doesn't work. When I present the View Controller, I do not see the stack view with the two buttons on it, the swipe gesture does not seem to be recognised at all, so I cannot dismiss the VC, and if I uncomment the constraint lines, I get BAD ACCESS when it executes them.
I have used constraints, stack views, gestures in other parts of the app (admittedly there's always been a storyboard behind them), but this is my first venture into doing away with them and it has me stumped. I'd like to be able to see and use the buttons (I'll add targets for them once I can see them), dismiss the VC using a swipe, and make the stack view take the entire view, none of which seems to be working. I'm probably missing something simple but can't see it for the life of me.
Upvotes: 0
Views: 67
Reputation: 100503
You declared the UIStackView
as a computed property it has to be a lazy var
lazy var stkMenu: UIStackView = {
let s = UIStackView(frame: CGRect.zero)
s.axis = .vertical
s.distribution = .fillEqually
s.alignment = .fill
s.translatesAutoresizingMaskIntoConstraints = false
return s
}()
also don't forget to un comment the constraints and comment this line
view.translatesAutoresizingMaskIntoConstraints = false
as by it you destroy the layout of the view
Upvotes: 2
Reputation: 77462
Looks like you simply mis-typed the declaration, plus you don't need to set the frame of the stack view...
Your code:
var stkMenu: UIStackView {
let s = UIStackView(frame: view.frame)
s.axis = .vertical
s.distribution = .fillEqually
s.alignment = .fill
s.translatesAutoresizingMaskIntoConstraints = false
return s
}
code that works (by un-commenting the constraints):
var stkMenu: UIStackView = {
let s = UIStackView() //frame: view.frame)
s.axis = .vertical
s.distribution = .fillEqually
s.alignment = .fill
s.translatesAutoresizingMaskIntoConstraints = false
return s
}()
Upvotes: 1