4

I am attempting to make a UIView/UIControl that people can drag up and reveal a text box, and then drag down to hide it. However, I have yet to find a method to make this "fluid" - it always seems to stop at random places and doesn't allow any more movement. At the moment I am using a UIView for the top part of the view and here is the current code:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

 UITouch *touch = [touches anyObject];

 if ([touch view] == topMenuView) {
  CGPoint location = [touch locationInView:self.superview];

  CGPoint locationInsideBox = [touch locationInView:self];

  CGPoint newLocation = location;
  newLocation.x = self.center.x;
  newLocation.y = newLocation.y + (self.frame.size.height - locationInsideBox.y) / 2;

  if ((self.superview.frame.size.height - newLocation.y) < (self.frame.size.height / 2) && (self.superview.frame.size.height - newLocation.y) > -32)
  {
   self.center = newLocation;
  }
  return;
 }
}

Any help would be much appreciated!

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
individualtermite
  • 3,615
  • 16
  • 49
  • 78

5 Answers5

1

I would use a pan gesture recognizer. The following code will simply move the view up and down along with the user's finger. If you want to limit how far up it moves, have it snap to place or have momentum you'll need to add to it.

UIView * view; // The view you're moving
CGRect originalFrame; // The frame of the view when the touch began

- (void) pan:(UIPanGestureRecognizer *)pan {
    switch (pan.state) {
        case UIGestureRecognizerStateBegan: {
            originalFrame = view.frame;
        } break;

        case UIGestureRecognizerStateChanged:
        case UIGestureRecognizerStateEnded: {
            CGPoint translation = [pan translationInView:view];
            CGRect frame = originalFrame;
            frame.origin.y += translation.y;
            view.frame = frame;
        } break;
    }
}
Cory Kilger
  • 13,034
  • 3
  • 33
  • 24
  • Thanks for your reply, Cory! I'm currently using "if (translation.y < (self.frame.size.height - topView.frame.size.height) && translation.y > 0)" to limit how far the view moves up. It works great for the first time, but for the second one it only adjusts in relation to the past frame. Is there some way to fix this? – individualtermite Oct 31 '10 at 02:46
0

Removing this line may well help you:

newLocation.y = newLocation.y + (self.frame.size.height - locationInsideBox.y) / 2;
Nick Hingston
  • 8,724
  • 3
  • 50
  • 59
0

What you're trying to accomplish is really nothing more than a scrollable view, so I would recommend using a UIScrollView.

Put your UIView in a UIScrollView with transparent background, and place the UIScrollView on top of your textbox. Set the correct contentSize and you're good to go.

Rits
  • 5,105
  • 4
  • 42
  • 53
  • The problem with this is approach the UIScrollView will have to be over the top of the "text box" (which i understood to be a UITextField or UITextView - maybe wrong!). Will need some special handling of responder chain or the z-order in this case. – Nick Hingston Oct 12 '10 at 09:22
0

use a uiview animation block to update the frame of the sliding view corresponding with the touch point recieved. set the animation blocks duration to something really short like .01 or lower.

nickthedude
  • 4,925
  • 10
  • 36
  • 51
0

I'd recommend splitting the issue in two:

  • Implement the view which has the text box at the bottom - You will just have to implement your own custom view/view controller.
  • Add your view as a subview of a UIScrollView.

This is a good tutorial which demonstrates proper initialization of UIScrollView and embedding content in it.

Custom views/controllers are a bit of a broader subject :)

Danra
  • 9,546
  • 5
  • 59
  • 117