Swift - to achieve free trade fish head followed by a list of slide automatically hide the navigation bar

Recent outbreaks, nothing to see fish IOSApp idle at home, find a list of goods the navigation bar auto-hide functionality is still very good, and decided to write himself a.

Busy Fish:
Free fish renderings

Ideas:
the navigation will follow under the tableView upward movement to achieve hidden. According to reappear on the pull. That is through tableView the delegate acquiring an offset contentOffset achieved while a judgment on the pull-down operation and the like.

Their effects:
Here Insert Picture Description

step

Initialization Project:
New Project. I am a pure code. So do not use StoryBoard . Use the SnapKit .
Not fit iPad, Project Genral years uncheck the iPad , and then SceneSessionabout are commented out. There are two parts, one in the AppDelegateinside part of the SceneDelegateinside. SceneDelegateYou can delete or full commenting out the code.

IOS 13 projects above the initial configuration:

  1. project Genral years uncheck iPad
  2. AppDelegateCommented Mark Lane as SceneSessionpart of the code
  3. Comment out SceneDelegatein all of the code, or deleted
  4. info.plist in deleted Application Scene Manifestitems
  5. In AppDelegateadd some initialization code, as follows:
    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.backgroundColor = UIColor.white
        let navVc = UINavigationController()
        navVc.viewControllers = [ViewController()]
        window?.rootViewController = navVc
        
        window?.makeKeyAndVisible()
        return true
    }

Run the simulator, normally appear white background add a navigation bar the initialization is complete.

Customize a navBar:
relatively simple, I put the code directly, replacing the original look navBarcan be.

class CustomNavBar:UINavigationBar{
    //存BarContentView的引用
    private var rootBackView:UIView?
    //具体的内容
    private var contentView:UIView?
    private var isInit = false
    private let contentViewHeight:CGFloat = 90
    
    override func layoutSubviews() {
        super.layoutSubviews()
        for subview in self.subviews {
            let stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("BarBackground") {
                subview.frame = self.bounds
            } else if stringFromClass.contains("UINavigationBarContentView") {
                subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: contentViewHeight + statusBarHeight)
                subview.snp.makeConstraints { (make) in
                    make.edges.equalToSuperview()
                }
                subview.backgroundColor = UIColor.white
                if rootBackView == nil{
                    rootBackView = subview
                }
            }
        }
        if !isInit{
            initSelf()
        }
    }
    //隐藏自己的方法
    public func toggleVisible(_ value:Bool){
        if value{
            UIView.animate(withDuration: 0.2, animations: {
                self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height:self.contentViewHeight + statusBarHeight)
                self.layoutIfNeeded()
            })
        }
        else{
            UIView.animate(withDuration: 0.2, animations: {
                self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: statusBarHeight)
                self.layoutIfNeeded()
            })
        }
    }
    
    private func initSelf(){
        isInit = true
        
        contentView = UIView()
        self.rootBackView?.addSubview(contentView!)
        contentView?.snp.makeConstraints({ (make) in
            make.height.equalTo(contentViewHeight)
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview()
        })
        
        let titleLabel:UILabel = UILabel()
        self.contentView?.addSubview(titleLabel)
        titleLabel.text = "搜索"
        titleLabel.textColor = UIColor.black
        titleLabel.backgroundColor = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1)
        titleLabel.layer.cornerRadius = 10
        titleLabel.clipsToBounds = true
        titleLabel.textAlignment = .center
        titleLabel.snp.makeConstraints { (make) in
            make.top.equalToSuperview()
            make.left.equalTo(20)
            make.right.equalTo(-20)
            make.height.equalTo(35)
        }
        
        let flit_btn = UIButton()
        self.contentView?.addSubview(flit_btn)
        flit_btn.setTitle("筛选", for: .normal)
        flit_btn.setTitleColor(UIColor.black, for: .normal)
        flit_btn.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        //flit_btn.backgroundColor = UIColor.lightGray
        flit_btn.snp.makeConstraints { (make) in
            make.bottom.equalToSuperview().offset(-1)
            make.right.equalToSuperview()
            make.width.equalTo(100)
            make.height.equalTo(40)
        }
        
        //navBar的分割线
        let darkLine = UIView()
        self.contentView?.addSubview(darkLine)
        darkLine.backgroundColor = UIColor(red: 235/255, green: 235/255, blue: 235/255, alpha: 1)
        darkLine.snp.makeConstraints { (make) in
            make.bottom.equalToSuperview()
            make.left.right.equalToSuperview()
            make.height.equalTo(1)
        }
        
        //用来遮挡进入statusBar的内容
        let maskView = UIView()
        self.rootBackView?.addSubview(maskView)
        maskView.backgroundColor = rootBackView?.backgroundColor
        maskView.snp.makeConstraints { (make) in
            make.left.top.right.equalToSuperview()
            make.height.equalTo(statusBarHeight)
        }
        
        
    }
}

In ViewControlleradding this in navBar, and a UITableView:
custom cell code here is not given. too easy. That is, a nib

class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource{


    private lazy var navBar:CustomNavBar = {
        let navBar = CustomNavBar()
        navBar.frame = CGRect(x: 0, y: 0, width: kScreenW, height: statusBarHeight+90)
        navBar.clipsToBounds = true
        return navBar
    }()
    private lazy var tableView:UITableView = {
        let view = UITableView()
        view.delegate = self
        view.dataSource = self
        view.showsVerticalScrollIndicator = false
        view.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "itemCell")
        return view
    }()
    private var navBarItem:UINavigationItem = UINavigationItem()
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        navigationController?.setNavigationBarHidden(true, animated: false)
        self.view.addSubview(navBar)
        navBar.items = [navBarItem]
        self.view.backgroundColor = UIColor(red: 235/255, green: 235/255, blue: 235/255, alpha: 1)
    }
    
    private func setupUI(){
        self.view.addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
    }

}

extension ViewController {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 40
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! CustomTableViewCell
        cell.setText("Test")
        return cell
    }
    
}

UI is over, the next into the core:
the definition of a few private variables

    //上次触碰TableView时的offset
    private var lastContentOffset:CGFloat = 0
    //触碰拖拽距离
    private var tempValue:CGFloat = 0
    //上次拖拽的方向 (1)-向上 (-1)-向下
    private var lastDirection:Int = 0

In extensionadding three methods in:

//当scollView被滑动时
func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //当scrollView被手指滑动时,如果不判断,在tableView被载入时会调用几次这个方法,造成自己隐藏。
        if scrollView.isTracking{
            //向下正 向上负
            let currentOffset = scrollView.contentOffset.y
            let offset = currentOffset - lastContentOffset
            //单次动作的幅度
            tempValue += offset
            if offset <= 0{
                //向上
                //变向清零
                if lastDirection != 0{
                    tempValue = 0
                    lastDirection = 0
                }
                scroll_handler(direct: -1, range: tempValue)
            }else{
                //向下
                //变向清零
                if lastDirection != 1{
                    tempValue = 0
                    lastDirection = 1
                }
                scroll_handler(direct: 1, range: tempValue)
            }
            lastContentOffset = currentOffset
        }
        
    }
    //当手指结束拖拽离开屏幕时
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        //如果没有完全隐藏
        if self.navBar.frame.height > statusBarHeight {
            //如果有向下的惯性
            if velocity.y > 0{
                //自动隐藏
                self.navBar.toggleVisible(false)
                tempValue = 0
            }
        }
    }
    //处理
    public func scroll_handler(direct:Int,range:CGFloat){
        if direct < 0{
            //向上移动的话直接显示navBar
            self.navBar.toggleVisible(true)
        }
        else{
            //向下移动就根据range来调整navBar的高度
            if self.navBar.frame.height > statusBarHeight {
                let _f = navBar.frame
                var height = statusBarHeight + 90 + range * -1
                height = height >= statusBarHeight ? height :statusBarHeight
                navBar.frame = CGRect(x: 0, y: 0, width: _f.width, height: height)
                
            }
        }
    }

Run can see the effects.

This is my first blog, pure hand to play, please indicate the source . If you find it useful, please point a praise it.

Released two original articles · won praise 3 · Views 452

Guess you like

Origin blog.csdn.net/qq_38419041/article/details/104275872