美文网首页Swift
scrollView头部拉伸效果 分类抽取 笔录

scrollView头部拉伸效果 分类抽取 笔录

作者: iOS_成才录 | 来源:发表于2016-05-24 16:09 被阅读973次
    • 先上效果图,希望对你有帮助:不论难易,坚持是一种态度。
      • 分类可实现多种效果:可控导航栏是否 隐藏,是只拉取高度,还是拉取宽高
    效果图1:导航栏隐藏,只拉取高度.gif 效果图2:导航栏显示,拉取款高度.gif

    。。。。。。。。

    • headerAllowScrolled 控制:头部视图 是否 跟随滚动
    效果图: 头部视图跟随滚动.gif 效果图 头部视图 不跟随其滚动.gif
    UIScrollView+topScaleHeaderView.swift 分类抽取
    • 在这里 我要 用到查看 导航控制器的 导航栏 是否隐藏 ,所以我 抽取了一个 UIView的分类
    extension UIView{
        /**
         找到 当前 view 所在的 控制器
         - returns: view 所在的 控制器
         */
        func viewController() -> UIViewController?{
            
            for(var next = self.superview; (next != nil); next = next!.superview){
                let nextResponder = next?.nextResponder()
                if ((nextResponder?.isKindOfClass(UIViewController.self)) != nil){
                    return (nextResponder as? UIViewController)!
                }
            }
            
            return nil
        }
    }
    
    • UIScrollView+topScaleHeaderView 分类
    import UIKit
    
    var headerView_Key = "headerView_Key"
    var headerView_H_key = "headerView_H_key"
    var headerAllowScrolled_Key = "headerAllowScrolled_Key"
    var headerView_MaxY_key = "headerView_MaxY_key"
    
    var headerView_H_Default: CGFloat = 250 // 默认 topScaleHeaderView 的高度
    var scaleType_key = 2 // 1: 只变高度拉伸,2:宽高度拉伸
    
    extension UIScrollView: UIScrollViewDelegate {
    
        //MARK: - 提供 扩展 只读 属性
        
        var headerAllowScrolled: Bool?{
            get{
                if let _ = objc_getAssociatedObject(self, &headerAllowScrolled_Key){
                    return objc_getAssociatedObject(self, &headerAllowScrolled_Key) as? Bool
                }
                return true
            }
        }
        
        var topScaleHeaderView_H: CGFloat{
            get{
                if let _ = objc_getAssociatedObject(self, &headerView_H_key){
                    return objc_getAssociatedObject(self, &headerView_H_key) as! CGFloat
                }
                return headerView_H_Default
            }
        }
        
        var topScaleHeaderView: UIView?{
            get{
                return objc_getAssociatedObject(self, &headerView_Key) as? UIView
            }
        }
        
        var topY: CGFloat{
            get{
                return objc_getAssociatedObject(self, &headerView_MaxY_key) as! CGFloat
            }
        }
    
        //MARK: - 提供 配置 接口
        func configBuildView(topScaleHeaderView:UIView,  headerAllowScrolled: Bool? = true) {
            
            // 设置 头部伸缩视图
            self.willChangeValueForKey("headerView_Key")
            objc_setAssociatedObject(self, &headerView_Key, topScaleHeaderView, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            self.didChangeValueForKey("headerView_Key")
            
            self.addSubview(topScaleHeaderView)
            
            // 设置 头部视图 最大Y值
            self.willChangeValueForKey("headerView_MaxY_key")
            objc_setAssociatedObject(self, &headerView_MaxY_key, getNavMaxY(), objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
            self.didChangeValueForKey("headerView_MaxY_key")
            
            // 设置 头部伸缩视图 高度, 若:不传高度,默认headerView_H_Default
            let h = topScaleHeaderView.frame.size.height > 0 ? topScaleHeaderView.frame.size.height : headerView_H_Default
            
            
            self.willChangeValueForKey("headerView_H_key")
            objc_setAssociatedObject(self, &headerView_H_key, h, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
            self.didChangeValueForKey("headerView_H_key")
            
            print("self.topScaleHeaderView_H: \(self.topScaleHeaderView_H)")
         
            self.contentInset = UIEdgeInsetsMake(self.topScaleHeaderView_H, 0, 0, 0)
            
            self.topScaleHeaderView?.frame = CGRectMake(0, -self.topScaleHeaderView_H, topScaleHeaderView.frame.size.width, self.topScaleHeaderView_H)
            
            // kvo 监听scrollView 滚动时 contentOffset改变
            self.addObserver(self, forKeyPath: "contentOffset", options: .New, context: nil)
            
            // 设置头部视图,是否跟随 scrollview视图滚动
    
            self.willChangeValueForKey("headerAllowScrolled_Key")
            objc_setAssociatedObject(self, &headerAllowScrolled_Key, headerAllowScrolled, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
            self.didChangeValueForKey("headerAllowScrolled_Key")
        }
        
        public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
          self.scrollViewDidScroll(self)
        }
        
       private func getNavMaxY() -> CGFloat{
            var navMaxY: CGFloat = 0
            if let currentVC = self.viewController(){
                if let _ = currentVC.navigationController{ // 有导航
                    if currentVC.navigationController!.navigationBarHidden{ // 隐藏
                        navMaxY =  0
                    }else{ // 未 隐藏
                        navMaxY = 64
                    }
                }
            }
            return navMaxY
        }
       
        public func scrollViewDidScroll(scrollView: UIScrollView) {
            // 导航 未 隐藏,var offsetY = scrollView.contentOffset.y
            // 导航  隐藏,  offsetY =scrollView.contentOffset.y + 64
            self.topScaleHeaderView?.center.x = self.center.x
            
            let offsetY = scrollView.contentOffset.y + self.topY
            let scale = -offsetY/self.topScaleHeaderView_H < 1 ? 1 : -offsetY/self.topScaleHeaderView_H
            
            if scaleType_key == 1{ // 只拉伸高度
                  self.topScaleHeaderView?.transform = CGAffineTransformMakeScale(1, scale)
            }else{ // 高度宽度都拉伸
                self.topScaleHeaderView?.transform = CGAffineTransformMakeScale(scale, scale)
            }
            self.topScaleHeaderView?.frame.origin.y = -self.topScaleHeaderView!.height
        }
    }
    

    demo

    import UIKit
    class ScaleImageDemoViewController: UITableViewController {
        let ScaleImageDemoViewController_CellID = "ScaleImageDemoViewController_CellID"
        var topScaleHeaderView: UIImageView = {
            let img = UIImageView(image: UIImage(named: "personIcon"))
            // 若 未 设置高度 为: 默认高度headerView_H_Default
            img.height = 250
            return img
        }()
        override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationController?.setNavigationBarHidden(true, animated: true)
            self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: self.ScaleImageDemoViewController_CellID)
         
            // 配置: 头部拉伸 视图:-》
                    // topScaleHeaderView 拉伸头部视图, 
                                    // 我们可以设置  topScaleHeaderView的高度,未设置为 默认分类中的headerView_H_Default, 
                    // headerAllowScrolled代表:头部视图 是否 随scrollView及其子类 滚动
                    // 当然:你也可以 配置 分类中的 scaleType_key = 1 // 默认 1: 只变高度拉伸,2:宽高度拉伸,我这里配置的是全局的,你也可以自己 扩展一个属性来控制每个scrollView及其子类的拉伸方式
            self.tableView.configBuildView(self.topScaleHeaderView, headerAllowScrolled: false)
        }
    }
    extension ScaleImageDemoViewController{
       override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 20
        }
        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier(self.ScaleImageDemoViewController_CellID)
            
            cell?.textLabel?.text = "\(indexPath.row )行"
            cell?.backgroundColor = UIColor.whiteColor()
            return cell!
        }
        
       override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            return 50
        }
    }
    

    相关文章

      网友评论

        本文标题:scrollView头部拉伸效果 分类抽取 笔录

        本文链接:https://www.haomeiwen.com/subject/fduzrttx.html