IOS控件系列--滚动列表上下滑动时顶部视图固定与滑动效果(Swift版)

一,效果图:




二。状态分析:

IOS这种滚动列表的滑动总共有四种状态(需要将弹性效果打开才有)

对于状态更新主要通过两个关键值判断:

let offset : CGPoint = change![NSKeyValueChangeKey.newKey] as! CGPoint
            let offsetY : CGFloat = offset.y
            
            let oldOffset : CGPoint = change![NSKeyValueChangeKey.oldKey] as! CGPoint
            let oldOffsetY : CGFloat = oldOffset.y
            
            let deltaOfOffsetY : CGFloat = offsetY - oldOffsetY

这些状态的,需要自己打印 offsetY 与  deltaOfOffsetY 这2个值的变化才能够知道

下面直接给出判断结果,注释有分析:

if deltaOfOffsetY < 0 && offsetY < 0 {      //单纯向下滑
            
                //print("208-----------: down")
                
//                if ((self.headerHeightConstraint?.constant)! >= self.headerHeight) {
//                    
//                    self.headerHeightConstraint?.constant = self.headerHeight;
//                    
//                } else {
//                    
//                    self.headerHeightConstraint?.constant -= deltaOfOffsetY;
//                    
//                }
            
            }
            
            if (deltaOfOffsetY > 0 && offsetY < 0){      //单纯向下拉,然后向上回弹
            
                    //print("224-----------: down---up")
               
            }
            
            if(deltaOfOffsetY > 0 && offsetY > 0 ){     //单纯向上滑
            
                 //print("229-----------: up")
                
                
                if ((self.headerHeightConstraint?.constant)! <= self.segmentMiniTopInset + 60) {
                    
                    self.headerHeightConstraint?.constant = self.segmentMiniTopInset + 60;
                    
                }else{
                    
                    self.headerHeightConstraint?.constant -= deltaOfOffsetY;
                    
                }
                
                //调整UItableView的位置 ,防止出现空白,,当列表中的内容大于列表可见框的高度时,才调整列表的位置
//                if (listView?.contentSize.height)! > (getScreenSize().height - headerHeight){
//                    
//                    var frame : CGRect = (listView?.frame)!
//                    
//                    if frame.origin.y <= 63{
//                        
//                        frame.origin.y = 63
//                        
//                    }else{
//                        
//                        frame.origin.y -= deltaOfOffsetY
//                    }
//                    
//                    listView?.frame = frame
//                }
                
                
                //调整搜索框的宽度。达到缩放动画效果
                if (labelWidthConstraint?.constant)! <= 280{
                
                    labelWidthConstraint?.constant = 280
                    
                }else{
                    
                    labelWidthConstraint?.constant -= deltaOfOffsetY
                }
                
            }
            
            if(deltaOfOffsetY < 0 && offsetY > 0 ){     //1.单纯向上滑,然后向下回弹  2.向下滑时--滚动视图有一部滑出了滚动视图,还未滑动到可视范围
            
                if offsetY > 200 { //2.向下滑时--滚动视图有一部滑出了滚动视图,还未滑动到可视范围
                
                }else{
                
                    if ((self.headerHeightConstraint?.constant)! >= self.headerHeight) {
                        
                        self.headerHeightConstraint?.constant = self.headerHeight;
                        
                    } else {
                        
                        self.headerHeightConstraint?.constant -= deltaOfOffsetY;
                        
                    }
                    
//                    var frame : CGRect = (listView?.frame)!
//                    
//                    if frame.origin.y >= 250{
//                        
//                        frame.origin.y = 250
//                        
//                    }else{
//                        
//                        frame.origin.y -= deltaOfOffsetY
//                    }
//                    
//                    listView?.frame = frame
                    
                    //调整搜索框的宽度。达到缩放动画效果
                    if (labelWidthConstraint?.constant)! >= getScreenSize().width - 40{
                        
                        labelWidthConstraint?.constant = getScreenSize().width - 40
                        
                    }else{
                        
                        labelWidthConstraint?.constant -= deltaOfOffsetY
                    }

                
                }
                 //print("250-----------:up-------- down")
                
            }
            
        }


三.头部视图高度的变化:

在第二步可以监听到UIScrollView的滚动状态变化,根据这些变化再配合头部视图的约束更新,即能达到头部视图的动态变化


四。UIScrollView kVO的全部代码如下:

 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        if keyPath == "contentOffset"{
            
            let offset : CGPoint = change![NSKeyValueChangeKey.newKey] as! CGPoint
            let offsetY : CGFloat = offset.y
            
            let oldOffset : CGPoint = change![NSKeyValueChangeKey.oldKey] as! CGPoint
            let oldOffsetY : CGFloat = oldOffset.y
            
            let deltaOfOffsetY : CGFloat = offsetY - oldOffsetY
            
            //print("203---------------deltaOfOffsetY:  \(deltaOfOffsetY)   offsetY:  \(offsetY)")
            
            
            if deltaOfOffsetY < 0 && offsetY < 0 {      //单纯向下滑
            
                //print("208-----------: down")
                
//                if ((self.headerHeightConstraint?.constant)! >= self.headerHeight) {
//                    
//                    self.headerHeightConstraint?.constant = self.headerHeight;
//                    
//                } else {
//                    
//                    self.headerHeightConstraint?.constant -= deltaOfOffsetY;
//                    
//                }
            
            }
            
            if (deltaOfOffsetY > 0 && offsetY < 0){      //单纯向下拉,然后向上回弹
            
                    //print("224-----------: down---up")
               
            }
            
            if(deltaOfOffsetY > 0 && offsetY > 0 ){     //单纯向上滑
            
                 //print("229-----------: up")
                
                
                if ((self.headerHeightConstraint?.constant)! <= self.segmentMiniTopInset + 60) {
                    
                    self.headerHeightConstraint?.constant = self.segmentMiniTopInset + 60;
                    
                }else{
                    
                    self.headerHeightConstraint?.constant -= deltaOfOffsetY;
                    
                }
                
                //调整UItableView的位置 ,防止出现空白,,当列表中的内容大于列表可见框的高度时,才调整列表的位置
//                if (listView?.contentSize.height)! > (getScreenSize().height - headerHeight){
//                    
//                    var frame : CGRect = (listView?.frame)!
//                    
//                    if frame.origin.y <= 63{
//                        
//                        frame.origin.y = 63
//                        
//                    }else{
//                        
//                        frame.origin.y -= deltaOfOffsetY
//                    }
//                    
//                    listView?.frame = frame
//                }
                
                
                //调整搜索框的宽度。达到缩放动画效果
                if (labelWidthConstraint?.constant)! <= 280{
                
                    labelWidthConstraint?.constant = 280
                    
                }else{
                    
                    labelWidthConstraint?.constant -= deltaOfOffsetY
                }
                
            }
            
            if(deltaOfOffsetY < 0 && offsetY > 0 ){     //1.单纯向上滑,然后向下回弹  2.向下滑时--滚动视图有一部滑出了滚动视图,还未滑动到可视范围
            
                if offsetY > 200 { //2.向下滑时--滚动视图有一部滑出了滚动视图,还未滑动到可视范围
                
                }else{
                
                    if ((self.headerHeightConstraint?.constant)! >= self.headerHeight) {
                        
                        self.headerHeightConstraint?.constant = self.headerHeight;
                        
                    } else {
                        
                        self.headerHeightConstraint?.constant -= deltaOfOffsetY;
                        
                    }
                    
//                    var frame : CGRect = (listView?.frame)!
//                    
//                    if frame.origin.y >= 250{
//                        
//                        frame.origin.y = 250
//                        
//                    }else{
//                        
//                        frame.origin.y -= deltaOfOffsetY
//                    }
//                    
//                    listView?.frame = frame
                    
                    //调整搜索框的宽度。达到缩放动画效果
                    if (labelWidthConstraint?.constant)! >= getScreenSize().width - 40{
                        
                        labelWidthConstraint?.constant = getScreenSize().width - 40
                        
                    }else{
                        
                        labelWidthConstraint?.constant -= deltaOfOffsetY
                    }

                
                }
                 //print("250-----------:up-------- down")
                
            }
            
        }
        
    }






猜你喜欢

转载自blog.csdn.net/d06110902002/article/details/78280128