Skip to content

Instantly share code, notes, and snippets.

@SunXiaoShan
Created June 19, 2020 06:26
Show Gist options
  • Save SunXiaoShan/8e292dc032055d5ccaaf1b989a8dc045 to your computer and use it in GitHub Desktop.
Save SunXiaoShan/8e292dc032055d5ccaaf1b989a8dc045 to your computer and use it in GitHub Desktop.
- (void)panGesture:(UIPanGestureRecognizer *)recognizer {
// Bottom Sheet 會隨著手勢移動跟著移動
[self moveViewWithGesture:recognizer];
// 當手移開螢幕時,Bottom Sheet 會根據新狀態移動到對應位置
if (recognizer.state != UIGestureRecognizerStateEnded) {
return;
}
// 以動畫效果來漸進畫面的移動
__weak __typeof(self)weakSelf = self;
[UIView animateKeyframesWithDuration:0.2
delay:0.0
options:UIViewKeyframeAnimationOptionAllowUserInteraction
animations:^{
const Director director = [recognizer velocityInView:weakSelf.view].y >= 0 ? down: up;
State state = weakSelf.lastStatus;
if (weakSelf.lastStatus == partial && director == up) {
state = expanded;
} else if (weakSelf.lastStatus == expanded && director == up) {
state = full;
}
if (weakSelf.lastStatus == full && director == down) {
state = expanded;
} else if (weakSelf.lastStatus == expanded && director == down) {
state = partial;
}
// handle
if (recognizer.view) {
if (state == expanded) {
CGFloat endLocation = recognizer.view.frame.origin.y;
if (endLocation > expandedViewYPosition &&
director == down) {
state = partial;
} else if (endLocation < expandedViewYPosition &&
director == up) {
state = full;
}
} else if (state == partial &&
weakSelf.lastStatus == partial) {
CGFloat endLocation = recognizer.view.frame.origin.y;
if (endLocation < expandedViewYPosition) {
state = expanded;
}
}
}
weakSelf.lastStatus = state;
[weakSelf moveView:state];
} completion:^(BOOL finished) {
// block fires when animaiton has finished
}];
}
// 依造不同狀態調整不同高度
- (void)moveView:(State)state {
CGFloat yPosition = fullViewYPosition;
if (state == partial) {
yPosition = partialViewYPosition;
} else if (state == expanded) {
yPosition = expandedViewYPosition;
}
const CGFloat width = self.view.frame.size.width;
const CGFloat height = self.view.frame.size.height;
CGRect rect = CGRectMake(0 , yPosition, width, height);
self.view.frame = rect;
}
// 根據手勢移動到哪邊,view 的 height 就變化多少
- (void)moveViewWithGesture:(UIPanGestureRecognizer *)recognizer {
const CGPoint translation = [recognizer translationInView:self.view];
const CGFloat minY = self.view.frame.origin.y;
if ((minY + translation.y >= fullViewYPosition) &&
(minY + translation.y <= partialViewYPosition)) {
const CGFloat width = self.view.frame.size.width;
const CGFloat height = self.view.frame.size.height;
const CGRect rect = CGRectMake(0 , minY + translation.y, width, height);
self.view.frame = rect;
[recognizer setTranslation:CGPointZero inView:self.view];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment