这是我的代码。
i通过在xib中定义视图来注册按钮动作。btn已连接到dismissButtonClick,但是当我单击按钮时它没有起作用。因此,我尝试了一种方法来覆盖touchesBegan Func,但没有用。
我的第三次尝试是手势注册。它也没有用。...
再也没有办法了。
请帮助我。
@objc public class CustomView : UIView {
static let xibName = "xibName"
@IBOutlet weak var mainView: UIView!
@IBOutlet weak var viewTopAnchor: NSLayoutConstraint?
@IBOutlet weak var btn: UIButton?
var completion: (() -> Void)?
var parentView : UIViewController!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public static func getInstance(_ vc : UIViewController, _ completion : (() -> Void)? ) -> UIView {
let view = Bundle.main.loadNibNamed(CustomView.xibName, owner: self, options: nil)?.first as! CustomView
view.parentView = vc
view.completion = completion
view.initUI()
return view
}
func initUI() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(CustomView.dismiss))
mainView.addGestureRecognizer(tapGestureRecognizer)
btn?.addTarget(self, action: #selector(CustomView.dismiss), for: .touchUpInside)
parentView.view.addSubview(self)
self.translatesAutoresizingMaskIntoConstraints = false
self.leadingAnchor.constraint(equalTo: parentView.view.leadingAnchor, constant: 0).isActive = true
self.trailingAnchor.constraint(equalTo: parentView.view.trailingAnchor, constant: 0).isActive = true
viewTopAnchor?.constant = -150
viewTopAnchor?.isActive = true
setNeedsDisplay()
layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 ) {
self.mainView.isHidden = false
self.showAnimation()
}
}
//top down anim
private func showAnimation(){
DispatchQueue.main.asyncAfter(deadline: .now() ) {
self.viewTopAnchor?.constant = 0
UIView.animate(withDuration: 0.5) {
self.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.dismissAnimation(self.duration)
}
}
}
}
private func dismissAnimation(_ duration : Double){
DispatchQueue.main.asyncAfter(deadline: .now() + duration - 0.5) {
self.viewTopAnchor?.constant = -150
UIView.animate(withDuration: 1) {
self.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.completion?()
self.removeFromSuperview()
}
}
}
}
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("touchBegan") // not called
let touch = touches.first
}
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
print("touchBegan") // not called
self.completion?()
self.btn?.removeTarget(self, action: #selector(dismissButtonClick), for: .touchUpInside)
self.removeFromSuperview()
}
@objc
func dismiss(){
print("dismiss") // not called
self.completion?()
self.removeFromSuperview()
}
@IBAction func dismissButtonClick(_ sender: Any) {
print("dismissButtonClick") // not called
self.completion?()
self.removeFromSuperview()
}
}
CustomView.getInstance(view, completion)
I have created one custom view with one button and wrote method which is called on button click. Please check it out it might be helpful in your case.
https://github.com/bhoomik/Custom_View_Demo
Custom View Code
//
// CustomView.swift
// Temp
//
// Created by Jaimin Modi on 19/02/20.
// Copyright © 2020 Jaimin Modi. All rights reserved.
//
import UIKit
//
// CustomView.swift
// Temp
//
//
import UIKit
class CustomView: UIView {
static let xibName = "CustomView"
@IBOutlet weak var viewTopAnchor: NSLayoutConstraint?
@IBOutlet weak var btn: UIButton?
var completion: (() -> Void)?
var parentView : UIViewController!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public static func getInstance(_ vc : UIViewController, _ completion : (() -> Void)? ) -> UIView {
let view = Bundle.main.loadNibNamed(CustomView.xibName, owner: self, options: nil)?.first as! CustomView
view.parentView = vc
view.completion = completion
// view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 120)
view.initUI()
return view
}
func initUI() {
// let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(CustomView.dismiss))
// mainView.addGestureRecognizer(tapGestureRecognizer)
//btn?.addTarget(self, action: #selector(CustomView.dismiss), for: .touchUpInside)
parentView.view.addSubview(self)
self.translatesAutoresizingMaskIntoConstraints = false
// self.leadingAnchor.constraint(equalTo: parentView.view.leadingAnchor, constant: 0).isActive = true
// self.trailingAnchor.constraint(equalTo: parentView.view.trailingAnchor, constant: 0).isActive = true
// viewTopAnchor?.constant = -150
// viewTopAnchor?.constant = 300
// viewTopAnchor?.isActive = true
let guide = self.parentView.view.safeAreaLayoutGuide
NSLayoutConstraint.activate(
[self.leftAnchor.constraint(equalTo: self.parentView.view.leftAnchor),
self.heightAnchor.constraint(equalToConstant: 50),
self.rightAnchor.constraint(equalTo: self.parentView.view.rightAnchor),
// segmentedControl!.topAnchor.constraint(equalTo: view.topAnchor, constant: 80)]
self.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)]
)
setNeedsDisplay()
layoutIfNeeded()
/* DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 ) {
self.mainView.isHidden = false
self.showAnimation()
}*/
}
@IBAction func dismissButtonClick(_ sender: Any) {
print("dismissButtonClick") // not called
// self.completion?()
// self.removeFromSuperview()
}
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
}
UIView Controller code
:
import UIKit
extension UIView {
class func fromNib<T: UIView>() -> T {
return Bundle(for: T.self).loadNibNamed(String(describing: T.self), owner: nil, options: nil)![0] as! T
}
}
class ViewController: UIViewController {
@IBOutlet weak var viewNav : CustomView!
var completion: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
/*viewNav = UIView.fromNib()
viewNav.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: viewNav.frame.size.height)
self.view.addSubview(viewNav)*/
CustomView.getInstance(self, completion)
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
[1]: https://github.com/bhoomik/Custom_View_Demo