iOS實現抽屜效果

pwmd 9年前發布 | 3K 次閱讀 Objective-C IOS

抽屜效果

在iOS中很多應用都用到了抽屜效果,例如騰訊的QQ,百度貼吧…

這里寫圖片描述———這里寫圖片描述

1. 最終效果如下圖所示

這里寫圖片描述———這里寫圖片描述

2.實現步驟

1.開始啟動的時候,新建3個不同顏色的View的

1.設置3個成員屬性,記錄三種顏色的View

@property (nonatomic,weak) UIView* redView;
@property (nonatomic,weak) UIView* greenView;
@property (nonatomic,weak) UIView* blueView;

2.初始化3個View

- (void)setUpthreeViews
{
    UIView *blueView = [[UIView alloc]initWithFrame:self.view.bounds];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    _blueView = blueView;

UIView *greenView = [[UIView alloc]initWithFrame:self.view.bounds];
greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenView];
_greenView = greenView;

UIView *redView = [[UIView alloc]initWithFrame:self.view.bounds];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
_redView = redView;

}</pre>

2.實現滑動的效果

1.通過-(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event方法來獲得當前點和初始點,從而計算出偏移量,然后計算redView的frame的值:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    //獲得當前點
    CGPoint currentPoint = [touch locationInView:_redView];
    //獲得起點
    CGPoint prePoint = [touch previousLocationInView:_redView];
    //計算在x軸方向上的偏移量
    CGFloat moveX = currentPoint.x - prePoint.x;
    //然后通過在x軸上的偏移量,計算redView的frame
    _redView.frame = [self framWithOffsetX:moveX];
}

  1. 假設x移到320時,y移動到60,算出每移動一點x,移動多少y

  2. offsetY = offsetX * 600 / 320 手指每移動一點,x軸偏移量多少,y偏移多少

  3. 為了好看,x移動到320,距離上下的高度需要保持一致,而且有一定的比例去縮放他的尺寸。
  4. touchMove只能拿到之前的frame.當前的高度 = 之前的高度 * 這個比例
    縮放比例:當前的高度/之前的高度 (screenH - 2 * offsetY) / screenH。
    當前的寬度保持不變就行。
  5. y值,計算比較特殊,不能直接用之前的y,加上offsetY,往左滑動,主視圖應該往下走,但是offsetX是負數,導致主視圖會往上走。所以需要判斷是左滑還是右滑

- (CGRect)framWithOffsetX:(CGFloat)offsetX
{
    //計算在y軸方向上的偏移量
    CGFloat offsetY = offsetX/SCREENWIDTH  MAXYOFFSET;
    //根據y方向的偏移量計算縮放比例
    CGFloat scale = (SCREENHEIGHT - 2offsetY)/SCREENHEIGHT;
    //如果x < 0表示左滑
    if (_redView.frame.origin.x < 0) {
        scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT;
    }

CGRect frame = _redView.frame;
//計算滑動之后的frame
CGFloat height = frame.size.height*scale;
CGFloat width  = frame.size.width;
CGFloat x = frame.origin.x + offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5;

return CGRectMake(x, y, width, height);

}</pre>
2.通過KVO來監聽redView的frame的變化,從而判斷redView是左滑還是右滑。往左移動,顯示右邊,隱藏左邊 往右移動,顯示左邊,隱藏右邊

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setUpthreeViews];

// 利用KVO時刻監聽_redView.frame改變
// Observer:誰需要觀察
// KeyPath:監聽的屬性名稱
// options: NSKeyValueObservingOptionNew監聽這個屬性新值
[_redView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

}

// 只要監聽的屬性有新值的時候,只要redView.frame一改變就會調用

  • (void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void *)context { if (self.redView.frame.origin.x > 0) {
      _greenView.hidden = NO;
    
    } else if(self.redView.frame.origin.x < 0){
      _greenView.hidden = YES;
    
    } }

// 當對象銷毀的時候,一定要移除觀察者

  • (void)dealloc { [_redView removeObserver:self forKeyPath:@"frame"]; }</pre>
    3.設置觸摸結束的時候,redView的frame。如果redView側滑沒有到屏幕的一半,則自動返回到初始位置。如果超過屏幕的一半,則停留在一個新的位置
    - (void)touchesEnded:(NSSet )touches withEvent:(UIEvent )event
    {
      CGFloat xPos = _redView.frame.origin.x;
      //大于屏幕的一半進入新的位置
      if (xPos > SCREENWIDTH*0.5) {
    
      [UIView animateWithDuration:0.5 animations:^{
          self.redView.frame = [self framWithBigThanX:ENDRIGHTX];
      }];
      return ;
    
    } //小于屏幕的一半,大于屏幕負一半的時候,則恢復到初始狀態 if (xPos < SCREENWIDTH0.5 && xPos > -SCREENWIDTH0.5) {
      [UIView animateWithDuration:0.5 animations:^{
          self.redView.frame = [UIScreen mainScreen].bounds;
      }];
      return ;
    
    } //xPos < -SCREENWIDTH*0.5的時候,進入新的位置 [UIView animateWithDuration:0.5 animations:^{
      self.redView.frame =  [self framWithSmallThanX:ENDLEFTX];
    
    }];

}

  • (CGRect)framWithBigThanX:(CGFloat)offsetX {

    CGFloat offsetY = offsetX/SCREENWIDTH MAXYOFFSET; CGFloat scale = (SCREENHEIGHT - 2offsetY)/SCREENHEIGHT;

    CGFloat height = SCREENHEIGHTscale; CGFloat width = SCREENWIDTH; CGFloat x = offsetX; CGFloat y = (SCREENHEIGHT- height) 0.5;

    return CGRectMake(x, y, width, height); }

  • (CGRect)framWithSmallThanX:(CGFloat)offsetX { CGFloat offsetY = offsetX/SCREENWIDTH MAXYOFFSET; CGFloat scale = (SCREENHEIGHT + 2offsetY)/SCREENHEIGHT;

    CGFloat height = SCREENHEIGHTscale; CGFloat width = SCREENWIDTH; CGFloat x = offsetX; CGFloat y = (SCREENHEIGHT- height) 0.5;

    return CGRectMake(x, y, width, height); }</pre>

 本文由用戶 pwmd 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!