Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
幻灯片菜单(汉堡菜单)iOS Swift_Ios_Swift_Menu - Fatal编程技术网

幻灯片菜单(汉堡菜单)iOS Swift

幻灯片菜单(汉堡菜单)iOS Swift,ios,swift,menu,Ios,Swift,Menu,我需要创建从右向左转换的幻灯片菜单,我已经成功创建了它,但当我按下菜单图标时,显示幻灯片菜单!!我不能在幻灯片菜单外按 如何创建从右向左过渡的动画?? 在幻灯片菜单外按时如何设置隐藏 滑动菜单类: import UIKit class SlideInMenu: NSObject, UIViewControllerAnimatedTransitioning { var isPresenting = false let dimmingView = UIView() func transitio

我需要创建从右向左转换的幻灯片菜单,我已经成功创建了它,但当我按下菜单图标时,显示幻灯片菜单!!我不能在幻灯片菜单外按

如何创建从右向左过渡的动画?? 在幻灯片菜单外按时如何设置隐藏

滑动菜单类:

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)
    }
 }

}
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
 }
}
视图控制器类:

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)
    }
 }

}
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
 }
}
输出:

你可以复制粘贴下面的代码,在现场观看

说明:

视图控制器:

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")
        }
    }
}
  • ViewController中添加了一个按钮,用于打开侧栏
  • 它向委托确认,以便它可以在侧边栏打开和关闭时侦听,以及用户是否选择了“否”选项
  • 侧栏:

  • 这是主要工作的重担

  • balck透明视图是关闭按钮,另一部分是NavigationViewController

  • 在“显示方法”中,“关闭”按钮设置为60宽度,导航vc视图使用约束与之对齐。请注意,导航vc的x位置设置为screenwidth的宽度

  • 在UIView.animate的帮助下,X位置设置为0,因此它从右向左设置动画

  • 单击任何选项或单击导航vc外部,即关闭按钮,将调用
    closeSidebar
    方法

  • closeSidebar还有一个UIViw.animate块,它再次将X位置设置为screenwidth,从而实现从左到右的动画。完成后,它将从视图层次结构中删除

  • ViewController正在确认此代理的
    sidebarDidClose
    方法中的
    SidebarDelegate
    ,您将知道侧栏已关闭,以及用户是否选择了任何选项

    视图控制器:

    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")
            }
        }
    }
    
    侧栏:

    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)
        }
    }
    
    代码的完整性

    导航视图

    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导航模型

    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)
        }
    }
    
    导航单元

    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
        }()
    }
    

    你能为你的问题添加视频吗?我在我的问题中添加了视频,单击(没有动画)并单击(隐藏它)@DavydovDenisanimate(持续时间:动画:)请问我的代码中的哪行有问题?如果我想在我的项目中写这段代码,如何在我的故事板中拖动它?@developer1996,你能和我分享你的项目吗。我可以在整合方面提供帮助。我已将我的项目发送到您的电子邮件。谢谢。我会调查的。@developer1996我已经向您发送了包含解决方案的电子邮件。如果遇到任何问题,请告诉我