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:
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:
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 SceneSession
about are commented out. There are two parts, one in the AppDelegate
inside part of the SceneDelegate
inside. SceneDelegate
You can delete or full commenting out the code.
IOS 13 projects above the initial configuration:
- project Genral years uncheck iPad
AppDelegate
Commented Mark Lane asSceneSession
part of the code- Comment out
SceneDelegate
in all of the code, or deleted - info.plist in deleted
Application Scene Manifest
items - In
AppDelegate
add 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 navBar
can 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 ViewController
adding 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 extension
adding 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.