4

I saw in my iPhone app that there is a gesture on the status bar which can access Notification Center. How can I implement that kind of transition in my app?. I think this is done with the swipe gesture recognizer, but how do I include a swipe gesture from top to bottom (how you can drag the Notification Center through its full transition)? Is there any sample code or something that can help me do this? Thaks in advance

Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
stackiphone
  • 1,245
  • 3
  • 19
  • 41
  • 3
    That's the Notification Center. Since that's a system wide gesture, if you implemented something like that in your app, I suspect either a) Apple would reject it because it conflicts with Notification Center or b) your users wouldn't see it because the notification center would appear. – Tomas McGuinness Apr 25 '12 at 14:39
  • 2
    @tomasmcguinness Te question's not about implementing a 2nd notification center, but about implementing a user interaction like this. – Kai Huppmann Apr 25 '12 at 14:44
  • @tomasmcguinness ,no no,,i just want to show a uiview controller like that,,that alll... – stackiphone Apr 25 '12 at 14:58
  • @Kai yess,corret,how to get swipe gesture from top to bottom?there is left and right swipe available... – stackiphone Apr 25 '12 at 15:00
  • @stackiphone I won't use a swipe gesture recognizer at all, see my answer below. – Kai Huppmann Apr 25 '12 at 15:27

3 Answers3

11

Should be easy to do. Let's say you have a UIView (mainView) from which you want to trigger the pull down thing.

  1. Put a subview (pulldownView) on mainView top-outside of visible area.
  2. Implement touchesBegan on mainView and check if the touch is in the top 30 pixels (or points).
  3. Implement touchesMoved where you check, if move direction is down and pulldownView not visible and if so drag the pulldownView down into visible area of main view or check if move direction is up and pulldownView visible and if so push upwards out of visible area.
  4. Implement touchesEnd where you end the drag or push movement by checking in which direction the pulldownView was moved.

EDIT:

Here's some sample code. Untested, may contain typos, maybe won't compile, but should contain the essential part needed.

//... inside mainView impl:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  UITouch *touch = (UITouch *)[touches anyObject];
  start = [touch locationInView:self.superview].y;
  if(start > 30 && pulldownView.center.y < 0)//touch was not in upper area of view AND pulldownView not visible
  {
    start = -1; //start is a CGFloat member of this view
  }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
  if(start < 0)
  {
    return;
  }
  UITouch *touch = (UITouch *)[touches anyObject];
  CGFloat now = [touch locationInView:self.superview].y;
  CGFloat diff = now - start;
  directionUp = diff < 0;//directionUp is a BOOL member of this view
  float nuCenterY = pulldownView.center.y + diff;
  pulldownView.center = CGPointMake(pulldownView.center.x, nuCenterY);
  start = now;
}


-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
  if (directionUp)
  {
    //animate pulldownView out of visibel area
    [UIView animateWithDuration:.3 animations:^{pulldownView.center = CGPointMake(pulldownView.center.x, -roundf(pulldownView.bounds.size.height/2.));}];
  }
  else if(start>=0)
  {
    //animate pulldownView with top to mainviews top
    [UIView animateWithDuration:.3 animations:^{pulldownView.center = CGPointMake(pulldownView.center.x, roundf(pulldownView.bounds.size.height/2.));}];
  }
}
Kai Huppmann
  • 10,705
  • 6
  • 47
  • 78
  • ,,thanks for your answer,,but am very new able to iOS,,so i think its not easy for me..lets try it...if there any sample ode or something u know,,that will be easer for me...thanks – stackiphone Apr 25 '12 at 15:13
  • @Kai's solution should work. I'd encourage you to think a little bit about how that functionality is going to work with Notification Center in your app, and whether it will be non-intuitive to your user or difficult to use. For instance, Android has a similar notification center functionality; in addition, you pull the screen down slightly in the browser to get to the address bar. It can be difficult to get to the address bar in the browser without accidentally getting the notification center instead. This may work fine in your app, just something to think about. – strings42 Apr 25 '12 at 15:17
  • 1
    @stackiphone added some sample code which might need some adjustments – Kai Huppmann Apr 25 '12 at 15:54
1

You can implement UISwipeGestureRecognizer to handle swipe gestures in your app, and specify the direction of the swipe to detect as UISwipeGestureRecognizerDirectionDown.

There's an Apple sample here. There are also some WWDC10 sessions that are worth a look. I'd suggest "Simplifying Touch Event Handling with Gesture Recognizers" and "Advanced Gesture Recognition" from that page.

strings42
  • 543
  • 3
  • 9
  • yes corret,thanks for your answer..i know how to implement the swipe gestue,,but how can i show that view like this? – stackiphone Apr 25 '12 at 15:01
0

I solved this problem by just using a subclassed UIView in a full sized UIScrollView. The UIView passes touch events to its underlaying view if the user touches a point that is not "dragabble".

@implementation MyCustomUIView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    // Check whether we are on the overlay
    if
    (
        point.y < 460.0f
        // Maybe some more restrictions here
    )
    {
        // Block the event, pass to parent
        return NO;
    }

    // Everything okay
    return YES;
}

@end

This code makes the UIScrollView only respond to touches under 460px. If your UIScrollView for example 800px height, you can touch it from 460px to 800px. Enough to open, close and use it. So if you got a full sized UIScrollView, you can drag it up to open it while you are able to "touch" the underlaying view. The benefit of this method is that all animations relay on the default behaviour and you dont have to implement it yourself.

Thomas Kekeisen
  • 4,355
  • 4
  • 35
  • 54