#selector function does not work in Swift 4.2 - ios

I have made an application with a button that is custom made programmatically. I wanted to add an #IBAction to it programmatically and I used the addTarget function to do so. The code does run but when the button is pressed, the function doesn't get called.
import UIKit
class MenuViewController: UIViewController {
#IBOutlet var LanguageLbl: UILabel!
var LanguageBtn = DropdownBtn()
var languagesArray = ["English" , "Русски" , "Español"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.layoutIfNeeded()
self.view.backgroundColor = UIColor.black
setupButtons()
}
func setupButtons() {
LanguageBtn = DropdownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
LanguageBtn.translatesAutoresizingMaskIntoConstraints = false
LanguageBtn.setTitle("English", for: .normal)
print("Adding target")
LanguageBtn.addTarget(self, action: #selector(languageBtnPressed(_:)), for: .touchUpInside)
print("Succesfully added target")
self.view.addSubview(LanguageBtn)
self.view.layoutIfNeeded()
LanguageBtn.leftAnchor.constraint(equalTo: LanguageLbl.leftAnchor, constant: 210).isActive = true
LanguageBtn.centerYAnchor.constraint(equalTo: LanguageLbl.centerYAnchor).isActive = true
LanguageBtn.widthAnchor.constraint(equalToConstant: 115).isActive = true
LanguageBtn.heightAnchor.constraint(equalToConstant: 40).isActive = true
LanguageBtn.dropView.dropDownOptions = languagesArray
}
#objc func languageBtnPressed(_ sender: UIButton) {
print("Btn Pressed")
}
In my example I have set the target for LanguageBtn called languageBtnPressed and when I run the code I get:
Adding target
Successfully added target
However, when I click the button it doesn't print:
Btn Pressed
What can be the problem here?
Here is my DropDownBtn class:
import Foundation
import UIKit
class DropdownBtn : UIButton, DropdownProtocol {
func dropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissDropDown()
}
var dropView = DropdownView()
var height = NSLayoutConstraint()
var isOpen = false
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.darkGray
dropView = DropdownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubview(toFront: dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropView.tableView.contentSize.height > 150 {
self.height.constant = 150
} else {
self.height.constant = self.dropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
dismissDropDown()
}
}
func dismissDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
and here is my DropDownProtocol
import Foundation
import UIKit
protocol DropdownProtocol {
func dropDownPressed(string: String)
}
and here is DropDownView class
import Foundation
import UIKit
class DropdownView : UIView, UITableViewDelegate, UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : DropdownProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.darkGray
self.backgroundColor = UIColor.darkGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.darkGray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.tableView.deselectRow(at: indexPath, animated: true)
}
}

Related

TableView didSelectRowAt not being called when nested in views

I have the following structure UIViewController -> UIView -> UIView -> UITableView (it's a dropdown menu), and the method didSelectRowAt is not being called, but if I skip the first view (that after VC), everything working perfectly. I saw a similar question here where was stated that you should use the method bringSubviewToFront but I tried that and it's not working (maybe I did it wrong).
Here is my code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let someView = someView()
someView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(someView)
}
}
class someView: UIView {
public lazy var button: DropDownButton = {
let button = DropDownButton(frame: .init(x: 0, y: 0, width: 100, height: 40))
button.setTitle("Colors", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.dropView.dropDownOptions = ["1","2","1","2"]
button.dropView.delegate = self
return button
}()
init() {
super.init(frame: .init(x: 0, y: 0, width: 300, height: 100))
addSubview(button)
addSubview(scrollButtons)
setUpConstraints()
}
}
class DropDownButton: UIButton {
public var dropView = DropDownView()
private var height = NSLayoutConstraint()
private var isOpen = false
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.darkGray
dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubviewToFront(dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
func dismissDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(
withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: .curveEaseInOut,
animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
self.height.constant = self.dropView.tableView.contentSize.height
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.3,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: .curveEaseInOut,
animations: {
self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(
withDuration: 0.3,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: .curveEaseInOut,
animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
}
}
class DropDownView: UIView {
var dropDownOptions = [String]()
var tableView = UITableView()
weak var delegate: DropDownDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.darkGray
self.backgroundColor = UIColor.darkGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.leftAnchor.constraint(equalTo: self.leftAnchor),
tableView.rightAnchor.constraint(equalTo: self.rightAnchor),
tableView.topAnchor.constraint(equalTo: self.topAnchor),
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension DropDownView: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.darkGray
return cell
}
}
extension DropDownView: UITableViewDelegate {
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
print("cell pressed")
self.delegate?.dropDownPressed(string: dropDownOptions[indexPath.row])
self.tableView.deselectRow(at: indexPath, animated: true)
}
}

Slide Menu (Hamburger Menu) iOS Swift

I need create slide menu with transition from right to left, I have succeeded to create it but when I press icon of menu show me slide menu without animation!! and I can’t hide it with press outside of slide menu!!
How can I create animation with transition from right to left??
How can I set hide when press outside of slide menu??
SlideInMenu Class:
import UIKit
class SlideInMenu: NSObject, UIViewControllerAnimatedTransitioning {
var isPresenting = false
let dimmingView = UIView()
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let toVC = transitionContext.viewController(forKey: .to),
let fromVC = transitionContext.viewController(forKey: .from) else { return }
let containerView = transitionContext.containerView
let finalWidth = toVC.view.bounds.width * 0.8375
let finalHeight = toVC.view.bounds.height
if (isPresenting) {
dimmingView.backgroundColor = UIColor(red: 32/255, green: 70/255, blue: 86/255, alpha: 0.8)
containerView.addSubview(dimmingView)
dimmingView.frame = containerView.bounds
containerView.addSubview(toVC.view)
toVC.view.frame = CGRect(x: -(finalWidth - toVC.view.bounds.width), y: 0, width: finalWidth, height: finalHeight)
}
let transform = {
self.dimmingView.alpha = 0.9
toVC.view.transform = CGAffineTransform(translationX: finalWidth - toVC.view.bounds.width, y: 0)
}
let identiy = {
self.dimmingView.alpha = 0.9
fromVC.view.transform = .identity
}
let duration = transitionDuration(using: transitionContext)
let isCancelled = transitionContext.transitionWasCancelled
UIView.animate(withDuration: duration, animations: {
self.isPresenting ? transform () : identiy()
}) { (_) in
transitionContext.completeTransition(!isCancelled)
}
}
}
ViewController Class:
import UIKit
class ViewController: UIViewController {
let transition = SlideInMenu()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func tapBtnMenu(_ sender: Any) {
guard let menuVC = storyboard?.instantiateViewController(withIdentifier: "MenuViewController") else { return }
menuVC.modalPresentationStyle = .overCurrentContext
menuVC.transitioningDelegate = self
present(menuVC, animated: true)
}
}
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transition.isPresenting = true
return transition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transition.isPresenting = false
return transition
}
}
Output:
You can copy paste the below code in see it a in live action.
Explanation:
ViewController:
A button is added to ViewController for the opening of Sidebar
It confirms to the delegate so that it can listen to when the sidebar gets opened and when it gets closed and whether the user has selected any option of not
Sidebar:
This does the heavy lifting of main work.
The balck transparent View is close button and the other part is NavigationViewController
In show method, the close button is set to 60 width and navigation vc view is aligned next to it using constraints. Note that the x position of navigation vc is set to the width of screenwidth.
With the help of UIView.animate, the X position is set to 0 thus it animates from right to left.
on click on any option or clicking on outside of nav vc i.e. close button, the closeSidebar method is called.
closeSidebar again has a UIViw.animate block which is setting X position to screenwidth again thus left to right animation. and when it gets completed it is removed from the view hierarchy.
The ViewController is confirming to SidebarDelegate in this delegate's sidebarDidClose method, you will get to know that side bar has been closed and if the user has selected any option or not.
ViewController:
import UIKit
class ViewController: UIViewController {
public let button: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Open Menu", for: .normal)
v.setTitleColor(.blue, for: .normal)
v.setTitleColor(UIColor.blue.withAlphaComponent(0.5), for: .highlighted)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
let constrains = [
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
]
NSLayoutConstraint.activate(constrains)
button.addTarget(self, action: #selector(didSelect(_:)), for: .touchUpInside)
}
#objc func didSelect(_ sender: UIButton){
SidebarLauncher.init(delegate: self).show()
}
}
extension ViewController: SidebarDelegate{
func sidbarDidOpen() {
}
func sidebarDidClose(with item: NavigationModel?) {
guard let item = item else {return}
switch item.type {
case .home:
print("called home")
case .star:
print("called star")
case .about:
print("called about")
case .facebook:
print("called facebook")
case .instagram:
print("instagram")
}
}
}
SideBar:
import UIKit
protocol SidebarDelegate {
func sidbarDidOpen()
func sidebarDidClose(with item: NavigationModel?)
}
class SidebarLauncher: NSObject{
var view: UIView?
var delegate: SidebarDelegate?
var vc: NavigationViewController?
init(delegate: SidebarDelegate) {
super.init()
self.delegate = delegate
}
public let closeButton: UIButton = {
let v = UIButton()
v.backgroundColor = UIColor.black.withAlphaComponent(0.5)
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
func show(){
let bounds = UIScreen.main.bounds
let v = UIView(frame: CGRect(x: bounds.width, y: 0, width: bounds.width, height: bounds.height))
v.backgroundColor = .clear
let vc = NavigationViewController()
vc.delegate = self
v.addSubview(vc.view)
v.addSubview(closeButton)
vc.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
closeButton.topAnchor.constraint(equalTo: v.topAnchor),
closeButton.leadingAnchor.constraint(equalTo: v.leadingAnchor),
closeButton.bottomAnchor.constraint(equalTo: v.bottomAnchor),
closeButton.widthAnchor.constraint(equalToConstant: 60),
vc.view.topAnchor.constraint(equalTo: v.topAnchor),
vc.view.leadingAnchor.constraint(equalTo: closeButton.trailingAnchor),
vc.view.bottomAnchor.constraint(equalTo: v.bottomAnchor),
vc.view.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: 0)
])
closeButton.addTarget(self, action: #selector(close(_:)), for: .touchUpInside)
self.view = v
self.vc = vc
UIApplication.shared.keyWindow?.addSubview(v)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.curveEaseOut], animations: {
self.view?.frame = CGRect(x: 0, y: 0, width: self.view!.frame.width, height: self.view!.frame.height)
self.view?.backgroundColor = UIColor.black.withAlphaComponent(0.5)
}, completion: {completed in
self.delegate?.sidbarDidOpen()
})
}
#objc func close(_ sender: UIButton){
closeSidebar(option: nil)
}
func closeSidebar(option: NavigationModel?){
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.curveEaseOut], animations: {
if let view = self.view{
view.frame = CGRect(x: view.frame.width, y: 0, width: view.frame.width, height: view.frame.height)
self.view?.backgroundColor = .clear
}
}, completion: {completed in
self.view?.removeFromSuperview()
self.view = nil
self.vc = nil
self.delegate?.sidebarDidClose(with: option)
})
}
}
extension SidebarLauncher: NavigationDelegate{
func navigation(didSelect: NavigationModel?) {
closeSidebar(option: didSelect)
}
}
For the completeness of the code
NavigationView
import Foundation
import UIKit
class NavigationView: UIView{
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit(){
addSubview(mainView)
mainView.addSubview(collectionView)
setConstraints()
}
func setConstraints() {
let constraints = [
mainView.topAnchor.constraint(equalTo: topAnchor),
mainView.leadingAnchor.constraint(equalTo: leadingAnchor),
mainView.bottomAnchor.constraint(equalTo: bottomAnchor),
mainView.trailingAnchor.constraint(equalTo: trailingAnchor),
collectionView.topAnchor.constraint(equalTo: mainView.topAnchor),
collectionView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor),
collectionView.bottomAnchor.constraint(equalTo: mainView.bottomAnchor),
collectionView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor)
]
NSLayoutConstraint.activate(constraints)
}
public let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
let v = UICollectionView(frame: .zero, collectionViewLayout: layout)
v.translatesAutoresizingMaskIntoConstraints = false
v.register(NavigationCell.self, forCellWithReuseIdentifier: "NavigationCell")
v.backgroundColor = .clear
return v
}()
public let mainView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .blue
return v
}()
}
NavigationViewController plus Navigation Model
import Foundation
import UIKit
protocol NavigationDelegate{
func navigation(didSelect: NavigationModel?)
}
enum NavigationTypes{
case home,star,about,facebook,instagram
}
struct NavigationModel {
let name: String
let type: NavigationTypes
}
class NavigationViewController: UIViewController{
var myView: NavigationView {return view as! NavigationView}
unowned var collectionView: UICollectionView {return myView.collectionView}
var delegate: NavigationDelegate?
var list = [NavigationModel]()
override func loadView() {
view = NavigationView()
}
override func viewDidLoad() {
super.viewDidLoad()
setupList()
collectionView.delegate = self
collectionView.dataSource = self
}
func setupList(){
list.append(NavigationModel(name: "Home", type: .home))
list.append(NavigationModel(name: "Star", type: .star))
list.append(NavigationModel(name: "About", type: .about))
list.append(NavigationModel(name: "Facebook", type: .facebook))
list.append(NavigationModel(name: "Instagram", type: .instagram))
}
}
extension NavigationViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return list.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "NavigationCell", for: indexPath) as! NavigationCell
let model = list[indexPath.item]
cell.label.text = model.name
return cell
}
}
extension NavigationViewController: UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
delegate?.navigation(didSelect: list[indexPath.item])
}
}
extension NavigationViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 45)
}
}
NavigationCell
import Foundation
import UIKit
class NavigationCell: UICollectionViewCell{
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit(){
[label,divider].forEach{contentView.addSubview($0)}
setConstraints()
}
func setConstraints() {
let constraints = [
label.centerYAnchor.constraint(equalTo: centerYAnchor),
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
divider.leadingAnchor.constraint(equalTo: leadingAnchor),
divider.bottomAnchor.constraint(equalTo: bottomAnchor),
divider.trailingAnchor.constraint(equalTo: trailingAnchor),
divider.heightAnchor.constraint(equalToConstant: 1)
]
NSLayoutConstraint.activate(constraints)
}
public let label: UILabel = {
let v = UILabel()
v.text = "Label Text"
v.textColor = .white
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
public let divider: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
return v
}()
}

Dropdown menu UIView opened from button in UITableviewCell not clickable outside of cell bounds

I am trying to make a button open up a dropdown menu styled UIView inside of a custom UITableViewCell. And it does open the UIView containing the other buttons. Great. However, the only clickable part is the tiny little bit of "1" inside the UITableViewCell. The rest of the dropdown menu is not clickable and you can click through it to the cell below. How can I make the button in the custom UITableViewCell open up the UIView with the dropdown menu and have each button inside the UIView clickable?
Here is what it's looking like now.
//The button inside the UITableViewCell:
class PriorityButton: UIButton, DropDownDelegate {
var dropDownView = DropDownView()
var height = NSLayoutConstraint()
var isOpen = false
override init(frame: CGRect) {
super.init(frame: frame)
dropDownView = DropDownView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
dropDownView.delegate = self
dropDownView.translatesAutoresizingMaskIntoConstraints = false
// button.setImage(UIImage(named: "UnChecked"), for: .normal)
// button.setImage(UIImage(named: "Checked"), for: .selected)
self.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
self.setTitleColor(.black, for: .normal)
self.backgroundColor = UIColor.white
self.layer.borderWidth = 2
self.layer.borderColor = UIColor.black.cgColor
self.titleLabel?.font = UIFont.init(name: "Avenir Next", size: 24)
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropDownView)
self.superview?.bringSubviewToFront(dropDownView)
dropDownView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropDownView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropDownView.heightAnchor.constraint(equalToConstant: 0)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropDownView.priorityTableView.contentSize.height > 300 {
self.height.constant = 300
} else {
self.height.constant = self.dropDownView.priorityTableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropDownView.layoutIfNeeded()
self.dropDownView.center.y += self.dropDownView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropDownView.center.y -= self.dropDownView.frame.height / 2
self.dropDownView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropDownView.center.y -= self.dropDownView.frame.height / 2
self.dropDownView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func dropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissDropDown()
}
}
// The Drop Down Menu view
class DropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
let priorityLevel = ["1", "2", "3", "4", "5"]
var priorityTableView = UITableView()
var delegate: DropDownDelegate!
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
priorityTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
priorityTableView.backgroundColor = .white
priorityTableView.delegate = self
priorityTableView.dataSource = self
priorityTableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(priorityTableView)
priorityTableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
priorityTableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
priorityTableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
priorityTableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return priorityLevel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath)
cell.textLabel?.text = priorityLevel[indexPath.row]
cell.backgroundColor = .white
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("test")
}
}
Expected results:
I want to click on the "1" button in the custom UITableViewCell and it show the dropdown menu UIView and be able to click on the buttons contained within the dropdown menu.
I think the problem is that the drop down is added to the super view of the cell (aka the tableView) and the delegate of the dropdown is assigned to the cell itself hence it won't respond to the tap gesture recognizer since the table view is not the delegate of it and the tap should occur on the cell, try adding it to the subView of the cell instead of the superView maybe that'll work. Good luck 👍

Constraint Crash after Dismissing View Controller

I'm a bit new to Xcode and been trying to do things programatically. I have View Controller A, B, C, and D. I have a back button on C, and D. When going from D to C using self.dismiss it works fine, however when I go from C to B I am getting a crash that looks like it's a constraint issue and I have no idea why.
Again, the crash occurs when going from C to B. The error says no common ancestor for DropDownButton, but there is no DropDownButton on ViewController B, it exists on C the one I am trying to dismiss.
I would like to know more about how the view controllers dismissing and Auto Layout works, could someone point me in the right direction please?
"oneonone.DropDownButton:0x7fcfe9d30660'🇺🇸+1 ⌄'.bottom"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal. userInfo: (null)
2018-11-09 19:56:22.828322-0600 oneonone[62728:4835265] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor
UPDATE TO QUESTIONS:
Here is View Controller C, included is the var, adding it to subview, and how I dismiss this view controller
lazy var countryCodes: DropDownButton = {
let button = DropDownButton(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
let us = flag(country: "US")
let br = flag(country: "BR")
let lightGray = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1)
button.backgroundColor = lightGray
button.setTitle(us + "+1 \u{2304}", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 20)
button.setTitleColor(UIColor.darkGray, for: .normal)
button.uiView.dropDownOptions = [us + "+1", br + "+55", "+33", "+17", "+19"]
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
[countryCodes].forEach{ view.addSubview($0) }
setupLayout()
}
func setupLayout(){
countryCodes.translatesAutoresizingMaskIntoConstraints = false
countryCodes.topAnchor.constraint(equalTo: instructionLabel.bottomAnchor, constant: 30).isActive = true
countryCodes.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -77.5).isActive = true
countryCodes.widthAnchor.constraint(equalToConstant: 85).isActive = true // guarantees this width for stack
countryCodes.heightAnchor.constraint(equalToConstant: 40).isActive = true
}
#objc func buttonPressed(){
self.dismiss(animated: true, completion: nil)
}
Here is the code in view controller B that (creates or presents?) View Controller C
#objc func phoneAuthButtonPressed(){
let vc = phoneAuthViewController()
self.present(vc, animated: true, completion: nil)
}
UPDATE 2: ADDING THE CUSTOM CLASS
Here is the button code that I used as a custom class following a tutorial, I believe the problem lies in here
protocol dropDownProtocol {
func dropDownPressed(string: String)
}
class DropDownButton: UIButton, dropDownProtocol {
var uiView = DropDownView()
var height = NSLayoutConstraint()
var isOpen = false
func dropDownPressed(string: String) {
self.setTitle(string + " \u{2304}", for: .normal)
self.titleLabel?.font = UIFont.systemFont(ofSize: 18)
self.dismissDropDown()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.gray
uiView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
uiView.delegate = self
uiView.layer.zPosition = 1 // show in front of other labels
uiView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(uiView)
self.superview?.bringSubviewToFront(uiView)
uiView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
uiView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
uiView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = uiView.heightAnchor.constraint(equalToConstant: 0)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // animates drop down list
NSLayoutConstraint.deactivate([self.height])
if self.uiView.tableView.contentSize.height > 150 {
self.height.constant = 150
} else {
self.height.constant = self.uiView.tableView.contentSize.height
}
if isOpen == false {
isOpen = true
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseInOut, animations: {
self.uiView.layoutIfNeeded()
self.uiView.center.y += self.uiView.frame.height / 2
}, completion: nil)
} else {
dismissDropDown()
}
}
func dismissDropDown(){
isOpen = false
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseInOut, animations: {
self.uiView.center.y -= self.uiView.frame.height / 2
self.uiView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class DropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : dropDownProtocol!
let lightGray = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1)
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = lightGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView) // can not come after constraints
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.textLabel?.font = UIFont.systemFont(ofSize: 14)
cell.textLabel?.textColor = UIColor.darkGray
cell.backgroundColor = lightGray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.tableView.deselectRow(at: indexPath, animated: true)
}
}
Replace your didMoveToSuperview function with this and it will work. This function also gets called when the view its removed from the superview and the superview will be nil and that's causing the crash.
override func didMoveToSuperview() {
if let superview = self.superview {
self.superview?.addSubview(dropView)
self.superview?.bringSubviewToFront(dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
}
As I can see, the error says that one of countryCodes buttons is located in the different view than instructionLabel. They should have the same parent if you want them to be constrained by each other.
Hi I think the problem occurs in the didMoveToSuperView() function, because it is called also when the view is removed from it's superview. so when you try to setup the anchor to something that does no more exist it crashes.
try something like this :
if let superview = self.superview {
superview.addSubview(uiView)
superview.bringSubviewToFront(uiView)
uiView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
uiView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
uiView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = uiView.heightAnchor.constraint(equalToConstant: 0)
}

Pop Up Menu Segue

I am making a pop up menu in Swift on Xcode 8.2.1, and I can't figure out how to make it segue correctly (It is being created programmatically right now so that it will have a animation when you open it).
import UIKit
var clickj = false
var st = String()
class ViewController: UIViewController {
var button = dropDownBtn()
override func viewDidLoad() {
super.viewDidLoad()
if clickj == true {
performSegue(withIdentifier: st, sender: nil)
}
// Do any additional setup after loading the view, typically from a nib.
//Configure the button
button = dropDownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
button.setTitle("Colors", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
//Add Button to the View Controller
self.view.addSubview(button)
//button Constraints
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
button.widthAnchor.constraint(equalToConstant: 100).isActive = true
button.heightAnchor.constraint(equalToConstant: 40).isActive = true
//Set the drop down menu's options
button.dropView.dropDownOptions = ["Blue", "Choices"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
protocol dropDownProtocol {
func dropDownPressed(string : String)
}
class dropDownBtn: UIButton, dropDownProtocol {
func dropDownPressed(string: String) {
print(string)
st = string
clickj = true
self.dismissDropDown()
}
var dropView = dropDownView()
var height = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.darkGray
dropView = dropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubview(toFront: dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
var isOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropView.tableView.contentSize.height > 150 {
self.height.constant = 150
} else {
self.height.constant = self.dropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class dropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : dropDownProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.darkGray
self.backgroundColor = UIColor.darkGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.darkGray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.tableView.deselectRow(at: indexPath, animated: true)
}
}
The problem is I have every thing set up to segue properly but I am still working on where I should place the if statement that will segue when the condition is true (mainly I am looking for some function I could place it in that would be called in the main ViewController when the button is clicked).
You are close... about all you need is to implement another delegate protocol.
Currently, your dropDownView is using dropDownProtocol to tell the button that a row was selected. What you also want is a protocol so the button can tell the view controller that it has dismissed itself, and to pass the selected string from the table.
Here is the code you presented, with very few changes. See the comments in the code. With your start, things should be pretty clear - feel free to ask for clarification if needed:
import UIKit
class ViewController: UIViewController, dropDownCallBackProtocol {
var button = dropDownBtn()
override func viewDidLoad() {
super.viewDidLoad()
//Configure the button
button = dropDownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
button.setTitle("Colors", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
//Add Button to the View Controller
self.view.addSubview(button)
//button Constraints
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
button.widthAnchor.constraint(equalToConstant: 100).isActive = true
button.heightAnchor.constraint(equalToConstant: 40).isActive = true
//Set the drop down menu's options
button.dropView.dropDownOptions = ["Blue", "Choices"]
// set the button's "vcCallBackDelegate"
button.vcCallBackDelegate = self
}
func dropDownCompleted(string: String) {
print("Inside View Controller:", string)
// this will be called when the un-show-drop-down animation is finished
// so you can perform your segue here
// performSegue(withIdentifier: string, sender: nil)
}
}
// protocol for the button to "call back" to the view controller (its parent)
protocol dropDownCallBackProtocol {
func dropDownCompleted(string : String)
}
// protocol for the table to "call back" to the button (its parent)
protocol dropDownProtocol {
func dropDownPressed(string : String)
}
class dropDownBtn: UIButton, dropDownProtocol {
var vcCallBackDelegate: dropDownCallBackProtocol?
func dropDownPressed(string: String) {
print("Inside button class:", string)
self.dismissDropDown(string)
}
var dropView = dropDownView()
var height = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.darkGray
dropView = dropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubview(toFront: dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
var isOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropView.tableView.contentSize.height > 150 {
self.height.constant = 150
} else {
self.height.constant = self.dropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissDropDown(_ selectedString: String) {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: {
b in
// tell the delegate the animation is complete, and pass the selected string
self.vcCallBackDelegate?.dropDownCompleted(string: selectedString)
})
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class dropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : dropDownProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.darkGray
self.backgroundColor = UIColor.darkGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.darkGray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.tableView.deselectRow(at: indexPath, animated: true)
}
}

Resources