我试图在父控制器的子视图中调用一个按钮。
我父控制器的代码是:
import Mapbox
import UIKit
class MapBoxViewController: UIViewController, MGLMapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
let mapView = MGLMapView(frame: view.bounds)
mapView.delegate = self
navigationItem.leftBarButtonItem = UIBarButtonItem(title:"Back", style: .plain, target: self, action: #selector(handleCancel))
let styleURL = NSURL(string: "mapbox://styles/abrach/ciicttgle001j9clv6ucj91ip")
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Set the map’s center coordinate and zoom level.
mapView.setCenter(CLLocationCoordinate2D(latitude: 45.52258, longitude: -122.6732), zoomLevel: 6, animated: false)
let point = MGLPointAnnotation()
point.coordinate = CLLocationCoordinate2D(latitude: 45.52258, longitude: -122.6732)
point.title = "Voodoo Doughnut"
point.subtitle = "22 SW 3rd Avenue Portland Oregon, U.S.A."
mapView.addAnnotation(point)
view.addSubview(mapView)
addBottomSheetView()
}
func addBottomSheetView() {
// 1- Init bottomSheetVC
let bottomSheetVC = BottomSheetViewController()
// 2- Add bottomSheetVC as a child view
self.addChildViewController(bottomSheetVC)
self.view.addSubview(bottomSheetVC.view)
bottomSheetVC.didMove(toParentViewController: self)
// 3- Adjust bottomSheet frame and initial position.
let height = view.frame.height
let width = view.frame.width
bottomSheetVC.view.frame = CGRect(x:0, y:self.view.frame.maxY, width: width, height: height)
}
func addSettings() {
// 1- Init bottomSheetVC
let settingsVC = settingsViewController()
// 2- Add bottomSheetVC as a child view
self.addChildViewController(settingsVC)
self.view.addSubview(settingsVC.view)
settingsVC.didMove(toParentViewController: self)
// 3- Adjust bottomSheet frame and initial position.
let height = view.frame.height
let width = view.frame.width
settingsVC.view.frame = CGRect(x:0, y:self.view.frame.maxY, width: width, height: height)
}
func handleCancel() {
dismiss(animated: true, completion: nil)
}
}
此函数在地图加载时将BottomSheetViewController调用为子视图。
BottomSheViewController的代码为:
import UIKit
class BottomSheetViewController: UIViewController {
var fullView: CGFloat {
return 65
}
var partialView: CGFloat {
return UIScreen.main.bounds.height - 57.5
}
var halfView: CGFloat {
return (UIScreen.main.bounds.height/2) + 60
}
let buttonBackgroundView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(r: 239, g: 239, b: 239)
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 8
view.layer.masksToBounds = true
return view
}()
lazy var addButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Add", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor(r: 88, g: 88, b: 88), for: .normal)
button.titleLabel?.font = UIFont(name: "Nunito", size: 17)
button.addTarget(self, action: #selector(handleTouch), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(BottomSheetViewController.panGesture))
view.addGestureRecognizer(gesture)
roundViews()
view.addSubview(buttonBackgroundView)
buttonBackgroundView.addSubview(addButton)
setupContainerViews()
}
func handleTouch() {
print("button pressed")
}
func roundViews() {
view.layer.cornerRadius = 18
view.clipsToBounds = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupContainerViews() {
buttonBackgroundView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -25).isActive = true
buttonBackgroundView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 10).isActive = true
buttonBackgroundView.heightAnchor.constraint(equalToConstant: 37.5).isActive = true
buttonBackgroundView.widthAnchor.constraint(equalToConstant: 90).isActive = true
addButton.centerXAnchor.constraint(equalTo: buttonBackgroundView.centerXAnchor).isActive = true
addButton.centerYAnchor.constraint(equalTo: buttonBackgroundView.centerYAnchor).isActive = true
}
func panGesture(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
let velocity = recognizer.velocity(in: self.view)
let y = self.view.frame.minY
if ( y + translation.y >= fullView) && (y + translation.y <= partialView ) {
self.view.frame = CGRect(x: 0, y: y + translation.y, width: view.frame.width, height: view.frame.height)
recognizer.setTranslation(CGPoint.zero, in: self.view)
}
if recognizer.state == .ended {
var duration = velocity.y < 0 ? Double((y - fullView) / -velocity.y) : Double((partialView - y) / velocity.y )
duration = duration > 1.3 ? 1 : duration
UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: [.allowUserInteraction], animations: {
if velocity.y >= 0 {
if y > self.halfView {
self.view.frame = CGRect(x: 0, y: self.partialView, width: self.view.frame.width, height: self.view.frame.height)
} else {
self.view.frame = CGRect(x: 0, y: self.halfView, width: self.view.frame.width, height: self.view.frame.height)
}
} else {
if y > self.halfView {
self.view.frame = CGRect(x: 0, y: self.halfView, width: self.view.frame.width, height: self.view.frame.height)
} else {
self.view.frame = CGRect(x: 0, y: self.fullView, width: self.view.frame.width, height: self.view.frame.height)
}
}
}, completion: nil)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [.allowUserInteraction], animations: {
let frame = self.view.frame
self.view.frame = CGRect(x: 0, y: self.halfView, width: frame.width, height: frame.height)
}, completion: nil)
}
}
在这个子视图中是一个“添加”按钮,我想从父母调用一个函数。目前,该按钮正在打印“按下按钮”。我希望该按钮调用父级中的addSettings()函数。我所做的尝试都没有被调用。我知道随着print语句的推出,按钮的交互工作正常。
有关如何从BottomSheetViewController调用该函数的任何建议吗?
答案 0 :(得分:1)
修改您的类BottomSheetViewController并添加一个成员变量 指向你的父母。
class BottomSheetViewController: UIViewController {
var parentVC : MapBoxViewController!
}
然后,将parentVC设置为MapBoxViewController的那个。
func addBottomSheetView() {
// 1- Init bottomSheetVC
let bottomSheetVC = BottomSheetViewController()
bottomSheetVC.parentVC = self
...
}
然后你可以调用BottomSheetViewController中的addSettings。 您可能还需要在主UI线程中调用addSettings。
答案 1 :(得分:0)
根据您的代码,没有子父关系,您可以像这样直接调用MapBoxViewController
类函数。您需要addTarget
作为父类,如MapBoxViewController
class BottomSheetViewController: UIViewController {
lazy var addButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Add", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor(r: 88, g: 88, b: 88), for: .normal)
button.titleLabel?.font = UIFont(name: "Nunito", size: 17)
button.addTarget(MapBoxViewController, action: #selector(MapBoxViewController.addSettings), for: .touchUpInside)
return button
}()
}
您需要设置子父母关系的其他方式,然后您可以像这样覆盖孩子addSettings
中的方法BottomSheViewController
class BottomSheetViewController: MapBoxViewController {
lazy var addButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Add", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor(r: 88, g: 88, b: 88), for: .normal)
button.titleLabel?.font = UIFont(name: "Nunito", size: 17)
button.addTarget(self, action: #selector(BottomSheetViewController.addSettings), for: .touchUpInside)
return button
}()
override func addSettings() {
super.addSettings() // this will call MapBoxViewController addSettings() method
}
}
答案 2 :(得分:0)
您可以为'BottomSheetViewController'提供一个闭包,并将MapBoxViewController.addBottomSheetView
中的闭包分配给bottomSheetVC
,在您只需调用addSettings
函数的闭包中
```
class BottomSheetViewController: UIViewController {
var aAddSettingsClosure: (() -> ())?
}
class MapBoxViewController: UIViewController, MGLMapViewDelegate {
func addBottomSheetView() {
// 1- Init bottomSheetVC
let bottomSheetVC = BottomSheetViewController()
bottomSheetVc.aAddSettingsClosure = { [weak self] in
// Call the addSettings() function here
self?.addSettings()
}
}
}
```
答案 3 :(得分:0)
我正在使用扩展程序在UIView中获取parentViewController:
extension UIResponder {
var parentViewController: MyViewController? {
return (self.next as? MyViewController) ?? self.next?.parentViewController
}
}
以及按钮中的操作:
myButton?.addTarget(parentViewController, action: #selector(parentViewController?.playTapped), for: .touchUpInside)
在视图控制器(MyViewController)中,我具有以下功能:
@objc func playTapped(_ sender:Any) {
//your code
}