iOS之下拉放大,上推縮小,一個方法搞定

最近加班加的比較多,再加上這個真的比較考驗邏輯,所以一段時間都沒寫東西了。來說說這次的功能,網上有很多類似的demo,但都是分開實現的,我把這兩個功能放到了一起,并且沒有使用AutoLayout,沒有用KVO,沒有用storyboard/xib.除了邏輯有點繞(現在不是流行玩算法么,那就搞的難理解點吧。。。),其他的還是簡單易懂的,而且我將重點數字使用的宏定義,擴展性很強。

先來看看效果吧。

講講大概的實現思路:
1?創(chuàng)建頭部的視圖和tableview,需要注意的是tableview要設置contentInset,contentInsent 的頂部要和頭部視圖的背景圖的高度一樣,否則會有空隙(或是有遮擋)。
myTableView.contentInset = UIEdgeInsetsMake(headRect.size.height-navHeight-navHeight, 0, 0, 0);
2?對頭部視圖的背景圖片的尺寸進行處理,當然,你也可以直接找一個適合尺寸的圖片,就不用處理圖片了,為了增加程序的擴展性,我就隨便選了張圖,并進行圖片尺寸處理。

  UIImage * image = [UIImage imageNamed:name];
  UIImage * newImg = [self image:image byScalingToSize:self.bounds.size];
  backgroundView.image = newImg;
  backgroundView.clipsToBounds = YES;//切掉圖片多余的部分
//處理圖片方法
- (UIImage *)image:(UIImage*)image byScalingToSize:(CGSize)targetSize {
    UIImage *sourceImage = image;
    UIImage *newImage = nil;
    
    UIGraphicsBeginImageContext(targetSize);
    
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = CGPointZero;
    thumbnailRect.size.width  = targetSize.width;
    thumbnailRect.size.height = targetSize.height;
    
    [sourceImage drawInRect:thumbnailRect];
    
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage ;
}

3.搞定了這些,準備工作就完成了,接下來,一個方法實現我們的下拉放大、上推縮小的功能,當然,重點和難點是邏輯,技術很easy。大家都知道UITableView是繼承UIScrollView的,利用UIScrollView的代理方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView;來實現。

下拉放大

在這個方法中,我們將功能分為兩部分,一個是下拉放大,這個是比較容易的,就是對頭部視圖的背景圖進行放大,調整frame,需要注意的是在此需要調整圖片的顯示方式,因為下拉和上推中圖片顯示的方式是不同的,否則即使你調整了frame,也不會按frame來顯示的。

  _myView.backgroundView.contentMode = UIViewContentModeScaleToFill;
  
  _myView.backgroundView.frame = CGRectMake(offset_Y*0.5 , -navHeight, VCWidth - offset_Y, headRect.size.height - offset_Y);

上推移動縮小

這個就比較難理解了,當然,我說的是中間對frame的算法,我們將三個視圖分開說。

  • 背景圖:先切換顯示模式,然后將y隨著tableview偏移移動到0,高度也是隨著tableview偏移,最終移動到需要的高度(Demo留的是44)
  _myView.backgroundView.contentMode = UIViewContentModeTop;

  _myView.backgroundView.frame = CGRectMake(0 ,navHeight* offset_Y/(headRect.size.height-navHeight-navHeight)-navHeight; , VCWidth , headRect.size.height -(navHeight + navHeight* offset_Y/(headRect.size.height-navHeight-navHeight)-navHeight;) - offset_Y);
  • 頭像:頭像需要隨著tableview的偏移而移動自身的位置,并且還要進行縮小。這里面就是一個線性方程的關系,和上面的的背景圖是一樣的。
  CGFloat width = offset_Y*(40-(VCWidth / 4))/(headRect.size.height-navHeight-navHeight)+(VCWidth / 4);
  _myView.headView.frame =CGRectMake(0, 0, width,width);
  _myView.headView.layer.cornerRadius =width*0.5;
  _myView.headView.center = _myView.backgroundView.center;
  • 簽名:簽名比較簡單,只要跟著頭像動就行,然后再根據偏移調整自己的透明度就行了。
  _myView.signLabel.frame =CGRectMake(0, CGRectGetMaxY(_myView.headView.frame), VCWidth, 40);
        
  _myView.signLabel.alpha = 1 - (offset_Y*3 / (headRect.size.height-navHeight-navHeight) /2);

然后就大功告成了,里的的邏輯挺麻煩的,但有初中的數學水平就夠了,因為都只是簡單的線性關系。最后是Demo,歡迎大家Star.

版權聲明:本文為 Crazy Steven 原創(chuàng)出品,歡迎轉載,轉載時請注明出處!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容