我在 iOS 应用程序中经常使用向上滑动面板,我发现诀窍是将自定义视图添加到故事板(或 xib 文件)中的视图控制器,但设置其框架,使其脱离屏幕。您可以使用以下命令确保视图在任何设备上保持在屏幕之外布局限制.
然后,只需在适当的时候为屏幕上的视图设置动画即可。例如。:
- (IBAction)showPanel:(id)sender
{
// panelShown is an iVar to track the panel state...
if (!panelShown) {
// myConstraint is an IBOutlet to the appropriate constraint...
// Use this method for iOS 8+ otherwise use a frame based animation...
myConstraint.constant -= customView.frame.size.height;
[UIView animateWithDuration:0.5 animations:^{
[self.view setNeedsLayout];
}];
}
else {
myConstraint.constant += customView.frame.size.height;
[UIView animateWithDuration:0.5 animations:^{
[self.view setNeedsLayout];
}];
}
}
如果您只想向上/向下滑动即可显示您可以使用的面板UISwipeGestureRecognizer
像这样:
- (void)viewDidLoad
{
[super viewDidLoad];
// iVar
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:swipeUp];
// Do the same again with swipeDown using UISwipeGestureRecognizerDirectionDown...
}
- (void)didSwipe:(UIGestureRecognizer *)swipe
{
if (swipe == swipeUp) {
// Show panel (see above)...
} else {
// Hide panel (see above)...
}
}
如果您希望面板像打开控制中心一样跟踪您的手指,那么您可以使用UIPanGestureRecognizer
并得到translationInView:
and velocityInView:
并相应调整面板。这是跟踪手指运动的代码片段,但使用touchesBegan:withEvent:
- (void)touchesMoved:withEvent:
and - (void)touchesEnded:withEvent:
中的方法UIViewController
给你尝尝:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Don't worry too much about buttonView this is another view that I animate upwards to get out the way of the panel as it slides in from the left...
[super touchesBegan:touches withEvent:event];
CGPoint loc = [[touches anyObject] locationInView:self.view];
// Save last touch for reference...
lastTouch = loc;
// leftBeginRect is an area where the user can start to drag the panel...
// trackFinger defines whether the panel should move with the users gestures or not...
if (CGRectContainsPoint(leftBeginRect, loc) && canTrack) {
trackFinger = YES;
}
// Left view is a reference to the panel...
else if (leftView.frame.size.width >= 300) {
// This means that the panel is shown and therefore should track the user's finger back towards the edge of the screen...
CGRect frame = CGRectMake(250, 0, 100, self.view.frame.size.height);
if (CGRectContainsPoint(frame, loc) && canTrack) {
trackFinger = YES;
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
CGPoint loc = [[touches anyObject] locationInView:self.view];
// Need to work out the direction in which the user is panning...
if (lastTouch.x > loc.x) {
currentFingerDirection = RHFingerDirectionLeft;
}
else {
currentFingerDirection = RHFingerDirectionRight;
}
lastTouch = loc;
if (trackFinger) {
if (loc.x <= 300) {
// This means that the panel is somewhere between fully exposed and closed...
// This is where the frame for the left view (and the constraints) are adjusted according to the user's current finger position...
CGRect frame = leftView.frame;
frame.size.width = loc.x;
[leftView setFrame:frame];
leftViewConstraint.constant = loc.x;
if (loc.x <= 80) {
float percentage = loc.x / 80;
int amount = 100 * percentage;
CGRect otherFrame = buttonView.frame;
otherFrame.origin.y = -amount;
[buttonView setFrame:otherFrame];
constraint.constant = constraintConstant + amount;
}
}
else {
CGRect frame = leftView.frame;
frame.size.width = 300;
[leftView setFrame:frame];
leftViewConstraint.constant = 300;
frame = buttonView.frame;
frame.origin.y = -100;
[buttonView setFrame:frame];
constraint.constant = constraintConstant + 100;
trackFinger = NO;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// This method works out if the panel should pop open or spring closed when the user ends the gesture...
[super touchesEnded:touches withEvent:event];
if (trackFinger) {
CGPoint loc = [[touches anyObject] locationInView:self.view];
if (loc.x >= 50 && currentFingerDirection == RHFingerDirectionRight) {
CGRect frame = leftView.frame;
frame.size.width = 300;
leftViewConstraint.constant = 300;
CGRect otherFrame = buttonView.frame;
otherFrame.origin.y = -100;
constraint.constant = constraintConstant + 100;
[UIView animateWithDuration:0.2 animations:^{
[leftView setFrame:frame];
[buttonView setFrame:otherFrame];
}];
}
else if (loc.x <= 250 && currentFingerDirection == RHFingerDirectionLeft) {
CGRect frame = leftView.frame;
frame.size.width = 0;
leftViewConstraint.constant = 0;
CGRect otherFrame = buttonView.frame;
otherFrame.origin.y = 0;
constraint.constant = constraintConstant;
[UIView animateWithDuration:0.2 animations:^{
[leftView setFrame:frame];
[buttonView setFrame:otherFrame];
}];
}
else if (loc.x <= 150) {
CGRect frame = leftView.frame;
frame.size.width = 0;
leftViewConstraint.constant = 0;
CGRect otherFrame = buttonView.frame;
otherFrame.origin.y = 0;
constraint.constant = constraintConstant;
[UIView animateWithDuration:0.2 animations:^{
[leftView setFrame:frame];
[buttonView setFrame:otherFrame];
}];
}
else {
CGRect frame = leftView.frame;
frame.size.width = 300;
leftViewConstraint.constant = 300;
CGRect otherFrame = buttonView.frame;
otherFrame.origin.y = -100;
constraint.constant = constraintConstant + 100;
[UIView animateWithDuration:0.2 animations:^{
[leftView setFrame:frame];
[buttonView setFrame:otherFrame];
}];
}
trackFinger = NO;
}
currentFingerDirection = RHFingerDirectionNone;
}
该代码非常复杂,但它会产生一个漂亮的面板动画,就像控制中心一样跟随您的手指。