How to replicate Messages bouncing bubbles in iOS 7

前端 未结 3 543
花落未央
花落未央 2020-12-13 15:47

When you are in a conversation within the Messages app in iOS 7, if you scroll up or down you will notice that the bubbles and more so the text saying when the messages were

相关标签:
3条回答
  • 2020-12-13 16:27

    If you want to replicate that effect yourself, you need UIKit Dynamics. I was interested in that effect myself and it was explained at WWDC this year.

    Take a look at WWDC Session 217: Exploring Scroll Views on iOS 7

    There are also read to use components on the internet, such as THSpringyCollectionView

    0 讨论(0)
  • 2020-12-13 16:32

    I was interested in that effect also and during my research on the web I found this tutorial - http://www.objc.io/issue-5/collection-views-and-uidynamics.html It is implementing the same idea.

    0 讨论(0)
  • 2020-12-13 16:36

    You can add a springy bounce to content in your scrollview like this:

    1. Set up a UIScrollview and add to your view.

      mainScroller = [UIScrollView new];
      mainScroller.frame = CGRectMake(0, 0, w, h);
      mainScroller.bounces = true;
      mainScroller.pagingEnabled = false;
      mainScroller.delegate = self;
      [self.view addSubview:mainScroller];
      
    2. Layout a UIView and add it within your scrollview.

      contentView = [UIView new];
      contentView.frame = CGRectZero;
      [mainScroller addSubview:contentView];
      
    3. Add subviews your your 'contentView'.

      UIView * unitView = [UIView new];
      unitView.frame = CGRectMake(0, yOff, w, 280);
      [contentView addSubview:unitView]; 
      
    4. Resize both contentView and scrollview to fit the content. Below w is view width and yOff the total cumulative height of the content.

      contentView.frame = CGRectMake(0, 0, w, yOff);
      mainScroller.contentSize = CGSizeMake(w, yOff);
      
    5. In your scrollViewDidScroll method, add the following code:

       float y = mainScroller.contentOffset.y;
       contentView.transform = CGAffineTransformMakeTranslation(0, y);
      
       for (UIView * sub in contentView.subviews){
           int index = (int)[contentView.subviews indexOfObject:sub];
           float delay = index * 0.03;
           float duration = 1.0f - delay;
      
           [UIView animateWithDuration:duration
                                 delay:delay
                usingSpringWithDamping:0.8
                 initialSpringVelocity:0.7
                               options:UIViewAnimationOptionCurveEaseInOut| UIViewAnimationOptionAllowUserInteraction
                            animations:^{
                                sub.transform = CGAffineTransformMakeTranslation(0, -y);
                           }
                       completion:^(BOOL finished){
                       }]; 
       }
      

    The UIViewAnimationOptionAllowUserInteraction animation option allows for you to interact with the content immediately. Tweak the delay, duration, spring dampening and spring velocity variables to suit your needs.

    The code could be further adapted to allow for touch detection; as it stands, the springy bounce originates at the top of the scrollView and descends down through the views, which for shorter scrollViews is barely noticeable.

    EDIT: Touch detection

    If you want to allow for touch detection, replace with these lines in your scrollViewDidScroll method:

    int index = (int)[contentView.subviews indexOfObject:sub];
    int deviation = abs(touchIndex - index);
    float delay = deviation * 0.03;
    float duration = 1.0f - delay;
    

    Where the new variable touchIndex is defined like so:

    -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    
        //grab the location of the touch event
        CGPoint location = [scrollView.panGestureRecognizer locationInView:scrollView];
        int yTouch = location.y; //grab y coordinate
        touchIndex = (yTouch - 100) / 100; //calculate the index of the cell, where 100 is the height of the cell
    
    }
    

    If you have dynamic cell heights, store them in an array e.g. 'selectedHeights'. Then update your scrollViewWillBeginDragging method for the below, where the 'tally' float is set to 70 to allow for a header.

    -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    
        //grab the location of the touch event
        CGPoint location = [scrollView.panGestureRecognizer locationInView:scrollView];
        int yTouch = location.y; //grab y coordinate
        float tally = 70.0f;
        for (int n = 0; n < selectedHeights.count; n++){
            float cellHeight = [selectedHeights[n] floatValue];
            tally += cellHeight;
            if (tally > yTouch){
                touchIndex = n;
                break;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题