弹出菜单继续
Pop Up Menu Segue
我正在 Xcode 8.2.1 上的 Swift 中制作一个弹出菜单,但我不知道如何正确地进行 segue(它现在正在以编程方式创建,所以打开它时会有动画)。
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)
}
}
问题是我已经将所有的东西都设置好以正确地进行 segue,但我仍在研究我应该在哪里放置 if 语句,该语句将在条件为真时进行 segue(主要是我正在寻找一些我可以放置它的函数当单击按钮时,将在主 ViewController 中调用它)。
你很接近了...你所需要的只是实现另一个委托协议。
目前,您的 dropDownView
正在使用 dropDownProtocol
告诉按钮已选择一行。您还需要一个协议,以便按钮可以告诉视图控制器它已自行关闭,并从 table.
传递选定的字符串
这是您提供的代码,几乎没有改动。查看代码中的注释。开始时,事情应该很清楚 - 如有需要,请随时要求澄清:
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)
}
}
我正在 Xcode 8.2.1 上的 Swift 中制作一个弹出菜单,但我不知道如何正确地进行 segue(它现在正在以编程方式创建,所以打开它时会有动画)。
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)
}
}
问题是我已经将所有的东西都设置好以正确地进行 segue,但我仍在研究我应该在哪里放置 if 语句,该语句将在条件为真时进行 segue(主要是我正在寻找一些我可以放置它的函数当单击按钮时,将在主 ViewController 中调用它)。
你很接近了...你所需要的只是实现另一个委托协议。
目前,您的 dropDownView
正在使用 dropDownProtocol
告诉按钮已选择一行。您还需要一个协议,以便按钮可以告诉视图控制器它已自行关闭,并从 table.
这是您提供的代码,几乎没有改动。查看代码中的注释。开始时,事情应该很清楚 - 如有需要,请随时要求澄清:
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)
}
}