我正在从事一个项目,因此我决定创建一个bottomsheet
,它主要可以工作,但是我仍然面临一些挑战,
我要显示的视图的基础是通过以下方式创建的:我将所需的UI组件嵌入到UIView中,以便UIView的底部成为bottomSheet的基础,并且它将完美放置在UIViewController的顶部
我能够拉起视图并在BottomSheet顶部添加另一个视图作为顶部导航,并模糊背景
我现在的问题是,在上拉视图时,buttomsheet视图控制器没有完全覆盖基本视图控制器,而实际上我想要的是在navigation view
上放置一个按钮,该按钮用作取消按钮
创建的模糊效果未设置动画,我已经尽我所能使动画无法与顶部导航视图的呈现相同,我希望能够从侧面进行动画处理并从也是。
以下是到目前为止我的代码很好
class BottomVC: UIViewController {
@IBOutlet weak var baseView: UIView!
@IBOutlet weak var holdView: UIView!
@IBOutlet weak var buttomBtn: UIButton!
@IBOutlet weak var priceLabel: UILabel!
@IBOutlet private var closeModalBtn: UIButton!
@IBOutlet weak var navView: UIView!
@IBOutlet weak var leftConstraint: NSLayoutConstraint!
@IBOutlet weak var rightConstraints: NSLayoutConstraint!
@IBOutlet weak var topConstraints: NSLayoutConstraint!
let fullView: CGFloat = 100
var partialView: CGFloat {
return UIScreen.main.bounds.height - (baseView.frame.maxY + UIApplication.shared.statusBarFrame.height) + 20
}
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(BottomVC.panGesture))
view.addGestureRecognizer(gesture)
roundViews()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
preparePartialView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.6, animations: { [weak self] in
let frame = self?.view.frame
let yComponent = self?.partialView
self?.view.frame = CGRect(x: 0, y: yComponent!, width: frame!.width, height: frame!.height)
})
}
@objc 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, options: [.allowUserInteraction], animations: {
if velocity.y >= 0 {
self.view.frame = CGRect(x: 0, y: self.partialView, width: self.view.frame.width, height: self.view.frame.height)
self.preparePartialView()
self.navView.isHidden = true
} else {
self.view.frame = CGRect(x: 0, y: self.fullView, width: self.view.frame.width, height: self.view.frame.height)
self.prepareFullView()
self.navView.isHidden = false
}
}, completion: nil)
}
}
func roundViews() {
view.layer.cornerRadius = 5
holdView.layer.cornerRadius = 3
view.clipsToBounds = true
}
func preparePartialView(){
let blurEffect = UIBlurEffect.init(style: .dark)
let visualEffect = UIVisualEffectView.init(effect: blurEffect)
let bluredView = UIVisualEffectView.init(effect: blurEffect)
bluredView.contentView.addSubview(visualEffect)
visualEffect.frame = UIScreen.main.bounds
bluredView.frame = UIScreen.main.bounds
for subview in view.subviews {
if subview is UIVisualEffectView {
subview.removeFromSuperview()
}
}
DispatchQueue.main.async {
self.leftConstraint.constant = 16
self.rightConstraints.constant = 16
self.topConstraints.constant = 0
self.holdView.layoutIfNeeded()
}
}
func prepareFullView(){
let blurEffect = UIBlurEffect.init(style: .dark)
let visualEffect = UIVisualEffectView.init(effect: blurEffect)
let bluredView = UIVisualEffectView.init(effect: blurEffect)
bluredView.contentView.addSubview(visualEffect)
visualEffect.frame = UIScreen.main.bounds
bluredView.frame = UIScreen.main.bounds
view.insertSubview(bluredView, at: 0)
DispatchQueue.main.async {
self.leftConstraint.constant = 0
self.rightConstraints.constant = 0
self.topConstraints.constant = 4
self.navView.topAnchor.constraint(equalTo: self.topLayoutGuide.topAnchor, constant: 0).isActive = true
self.holdView.topAnchor.constraint(equalTo: self.navView.bottomAnchor, constant: 4).isActive = true
self.navView.layoutIfNeeded()
self.holdView.layoutIfNeeded()
}
}
}
基本视图控制器
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
addBottomSheetView()
}
func addBottomSheetView() {
// 1- Init bottomSheetVC
let bottomSheetVC = BottomVC()
// 2- Add bottomSheetVC as a child view
self.addChild(bottomSheetVC)
self.view.addSubview(bottomSheetVC.view)
bottomSheetVC.didMove(toParent: self)
// 3- Adjust bottomSheet frame and initial position.
let height = view.frame.height
let width = view.frame.width
bottomSheetVC.view.frame = CGRect(0, self.view.frame.maxY, width, height)
}
此外,如果我单击BaseViewController中的任何按钮并返回到BaseViewController,则按钮表将变为两倍。任何帮助表示赞赏