日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php 仿高德,仿高德路线规划滑动效果

發(fā)布時(shí)間:2025/3/12 php 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php 仿高德,仿高德路线规划滑动效果 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

因?yàn)轫?xiàng)目有個(gè)界面要模仿高德地圖路徑規(guī)劃滑動(dòng)效果,因此寫了demo,并簡(jiǎn)單說下分析過程。

高德地圖效果演示:

仿高德路線規(guī)劃滑動(dòng).gif

demo效果演示:

高德地圖規(guī)劃滑動(dòng).gif

一. 分析

首先,我們可以看出這個(gè)滾動(dòng)的視圖應(yīng)該是UIScrollView或者UIScrollView的子類(比如:UITableView);

其次,從高德地圖里的視圖一開始的滑動(dòng),可以看出這個(gè)滑動(dòng)是平穩(wěn)的滑動(dòng),沒有加速和減速,因此這里不可能是UIScrollView的滾動(dòng)效果,因?yàn)閁IScrollView的滾動(dòng)效果是由一個(gè)加減速的過程,因此一開始滑動(dòng),應(yīng)該是通過滑動(dòng)手勢(shì)UIPanGestureRecognizer,來移動(dòng)UIScrollView的y值來移動(dòng)

接著滑動(dòng)到指定位置之后,UIScrollView的y值固定不動(dòng),然后UIScrollView的內(nèi)容進(jìn)行滾動(dòng)。這里就涉及到滑動(dòng)手勢(shì)UIPanGestureRecognizer的滑動(dòng),還有UIScrollView內(nèi)部的滾動(dòng)的處理。高德地圖的演示效果里面,一開始滑動(dòng)視圖向上移動(dòng),移動(dòng)到指定的點(diǎn)之后,立馬就變成視圖的滾動(dòng),這里可以分析,UIScrollView既支持手勢(shì)的滑動(dòng)又支持視圖的滾動(dòng),只是通過條件來判斷限制兩者的執(zhí)行邏輯。

同時(shí)我們可以看到,如果一開始向上拉動(dòng)視圖力度大一點(diǎn),視圖會(huì)直接滾動(dòng)到指定位置,如果力度小,就恢復(fù)到原來位置,因此這里需要依據(jù)手勢(shì)滑動(dòng)的加速度來進(jìn)行判斷處理。

而當(dāng)你滑動(dòng)到中間位置的時(shí)候,也需要依據(jù)最后滑動(dòng)的位置來判斷應(yīng)該動(dòng)畫滾動(dòng)到上方還是下方。

最后滑動(dòng)的時(shí)候上方的視圖和滑動(dòng)視圖本身有背景顏色的漸變效果,這里需要依據(jù)滑動(dòng)距離來判斷。

二.代碼分析:

首先由于滾動(dòng)視圖(demo里面是UITableView)需要支持手勢(shì)滑動(dòng)和內(nèi)部滾動(dòng),因此需要寫一個(gè)類FJBaseTableView繼承自UITableView,然后在FJBaseTableView的實(shí)現(xiàn)里面重寫如下方法:

// 當(dāng)有 多個(gè)手勢(shì) 都可以 響應(yīng)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

return YES;

}

來支持響應(yīng)多個(gè)手勢(shì)。

然后給滾動(dòng)視圖tableView添加滑動(dòng)手勢(shì),當(dāng)tableView從底部滑動(dòng)到頂部指定位置時(shí),應(yīng)該限制tableView內(nèi)部的視圖滾動(dòng)。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

if (self.tableView.frame.origin.y > _scrollViewStartPositionY) {

[scrollView setContentOffset:CGPointMake(0, 0)];

}

}

這里的_scrollViewStartPositionY是頂部指定位置。

接著看下手勢(shì)滑動(dòng)的處理邏輯:

#pragma mark - 手勢(shì)處理

- (void)handlePanGesture:(UIPanGestureRecognizer *)sender {

if (sender.state == UIGestureRecognizerStateBegan) {

_beganPoint = [sender locationInView:sender.view.superview];

_curPoint = sender.view.center;

_topTipContainerViewCurrentY = _topContainerView.frame.origin.y;

_previousOffsetY = self.tableView.contentOffset.y;

} else if(sender.state == UIGestureRecognizerStateChanged) {

CGPoint point = [sender locationInView:sender.view.superview];

CGFloat offsetY = _previousOffsetY - self.tableView.contentOffset.y;

NSInteger y_offset = point.y - _beganPoint.y - offsetY;

if (sender.view.frame.origin.y >= _scrollViewStartPositionY || (self.tableView.contentOffset.y == 0 && self.tableView.contentSize.height > self.tableView.frame.size.height)) {

sender.view.center = CGPointMake(_curPoint.x, _curPoint.y + y_offset);

[self updateViewControlsWithSlideOffset:y_offset];

}

if (sender.view.frame.origin.y > _scrollViewLimitMaxY) {

sender.view.y = _scrollViewLimitMaxY;

[self updateViewControlsWithSlideUp:NO];

}

else if(sender.view.frame.origin.y < _scrollViewStartPositionY) {

sender.view.y = _scrollViewStartPositionY;

[self updateViewControlsWithSlideUp:YES];

}

} else if(sender.state == UIGestureRecognizerStateEnded) {

if (sender.view.frame.origin.y <= _scrollViewStartPositionY || sender.view.frame.origin.y > _scrollViewLimitMaxY) {

if (sender.view.frame.origin.y <= _scrollViewStartPositionY) {

[self updateViewControlsWithSlideUp:YES];

}

if (sender.view.frame.origin.y > _scrollViewLimitMaxY) {

[self updateViewControlsWithSlideUp:NO];

}

return;

}

// 滑動(dòng)速度處理

CGPoint velocity = [sender velocityInView:self.view];

CGFloat speed = 350;

if (velocity.y < - speed) {

// 快速向上

[self tableViewMoveToTop];

return;

} else if (velocity.y > speed) {

// 快速向下

[self tableViewMoveToBottom];

return;

}

// 滑動(dòng)臨界值

CGFloat criticalValue = _scrollViewLimitMaxY/2.0;

if (sender.view.frame.origin.y <= criticalValue) {

[self tableViewMoveToTop];

} else {

[self tableViewMoveToBottom];

}

}

}

這里幾個(gè)點(diǎn)需要注意:

_beganPoint、_curPoint兩個(gè)參數(shù)是用來計(jì)算手勢(shì)滑動(dòng)距離然后調(diào)整scrollView的滑動(dòng)距離。而_previousOffsetY是用來記錄滑動(dòng)之前tableView的內(nèi)部視圖的偏移距離,因?yàn)楫?dāng)tableView滑動(dòng)到頂部指定位置后,tableView開始滾動(dòng),這時(shí)候tableView向下滑動(dòng)是先移動(dòng)了tableView內(nèi)部的滾動(dòng)距離,然后才是滑動(dòng)距離,因此需要將這部分值先記錄,然后去除掉,才是tableView向下真正需要滑動(dòng)的距離。

CGFloat offsetY = _previousOffsetY - self.tableView.contentOffset.y;

NSInteger y_offset = point.y - _beganPoint.y - offsetY;

2.滑動(dòng)過程中,頂部視圖的移動(dòng)和漸變處理,這里先依據(jù)滑動(dòng)的距離算出tableView滑動(dòng)距離與tableView最大滑動(dòng)距離的比值,然后再算出頂部視圖需要移動(dòng)的距離和背景的透明度。

- (void)updateViewControlsWhenSliding {

if (self.tableView.frame.origin.y > _scrollViewStartPositionY && self.tableView.frame.origin.y < _scrollViewLimitMaxY) {

CGFloat offsetLimitDistance = _scrollViewLimitMaxY - _scrollViewStartPositionY;

CGFloat offsetDistance = self.tableView.frame.origin.y - _scrollViewStartPositionY;

if (offsetDistance > 0 && offsetDistance < offsetLimitDistance) {

CGFloat topViewHeight = [FJFTopContainerView viewHeight];

CGFloat topViewHeightOffset = offsetDistance * (topViewHeight / offsetLimitDistance);

CGFloat viewAlpha = offsetDistance / offsetLimitDistance;

_topContainerView.y = topViewHeightOffset - topViewHeight;

_topContainerView.alpha = viewAlpha;

}

}

}

3.滑動(dòng)速度處理,依據(jù)velocityInView函數(shù)獲取速度值,然后依據(jù)當(dāng)前速度值大小和正負(fù)和設(shè)定的速度值比較來判斷是否需要向上或向下移動(dòng)。

// 滑動(dòng)速度處理

CGPoint velocity = [sender velocityInView:self.view];

CGFloat speed = 350;

if (velocity.y < - speed) {

// 快速向上

[self tableViewMoveToTop];

return;

} else if (velocity.y > speed) {

// 快速向下

[self tableViewMoveToBottom];

return;

}

4.滑動(dòng)臨界值處理,判斷最后滑動(dòng)位置與底部指定位置一半,兩個(gè)值的大小來判斷滑動(dòng)的方向。

// 滑動(dòng)臨界值

CGFloat criticalValue = _scrollViewLimitMaxY/2.0;

if (sender.view.frame.origin.y <= criticalValue) {

[self tableViewMoveToTop];

} else {

[self tableViewMoveToBottom];

}

三.總結(jié)

這里最主要就是介紹了分析的思路,來找出可靠的實(shí)現(xiàn)方法,具體邏輯,詳見demo

總結(jié)

以上是生活随笔為你收集整理的php 仿高德,仿高德路线规划滑动效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜va| 在线精品视频免费观看 | 国产日本一区二区 | 黄色片在线免费 | 国产一级片 | 国产精品69久久久久 | 91禁外国网站 | 岳乳丰满一区二区三区 | 91亚洲精品久久久蜜桃网站 | 激情五月婷婷小说 | 国产三级第一页 | 手机av免费在线观看 | 秋霞7777鲁丝伊人久久影院 | 国产人妖在线 | 天堂网在线观看 | 搡老熟女国产 | 亚洲一卡二卡在线观看 | 亚洲精品视频中文字幕 | 永久免费的网站入口 | 亚洲欧美网址 | 欧美日韩在线中文字幕 | www.亚洲一区二区三区 | 亚洲少妇15p | 国产69久久 | 久久免费看视频 | 日人视频 | 青青草华人在线视频 | 97在线精品 | 日日cao | 久久久久久亚洲精品中文字幕 | 一级黄片毛片 | 久草免费在线播放 | 超碰97在线资源站 | 天堂va欧美va亚洲va老司机 | 亚洲国产一区二区三区a毛片 | 99精品久久99久久久久 | 国产成人在线电影 | 九色蝌蚪9l视频蝌蚪9l视频 | 国产福利第一页 | 俺去射| 韩国一级淫片 | 男女做激情爱呻吟口述全过程 | 男生操女生在线观看 | 久久ww| 国产99999 | 99精品在线播放 | 日本午夜激情 | 一级bbbbbbbbb毛片 | 少妇激情网 | 欧美成人三区 | 日韩精品久久一区二区 | 黄网址在线观看 | av在线天堂网 | 国产一区二区三区视频在线播放 | 久久精品日韩 | 国产精品11 | julia一区二区中文久久97 | 久久小视频 | 欧美成人免费 | 日本免费小视频 | 91亚洲国产成人精品一区 | 成年人在线播放视频 | 国产男女无套免费网站 | 男人透女人免费视频 | 丝袜 中出 制服 人妻 美腿 | 九九热在线视频 | 乳女教师の诱惑julia | 浮生影视在线观看免费 | 91一区二区三区四区 | 色交视频| 91精品欧美一区二区三区 | 韩国美女福利视频 | 日本wwwwww| 亚洲黄色短视频 | 国产视频综合在线 | 女人做爰全过程免费观看美女 | 日本一区二区三区在线播放 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 丰满人妻一区二区三区53 | 亚洲精品91在线 | 国产性爱精品视频 | 毛片无码一区二区三区a片视频 | 中文字幕一区二区三区视频 | 禁漫天堂免费网站 | 国产精品视频久久久 | 成人激情视频在线 | 99久久久无码国产精品衣服 | 91视频青青草 | 成人在线观看网站 | 天天干天天色天天 | 亚洲青青草 | av五十路| 久久亚洲精精品中文字幕早川悠里 | 亚洲黄色在线观看视频 | 久久久久久久久久久久久久久久久久 | 日韩怡春院 | 天天操天天操天天操天天操天天操 | 在线91视频 | 欧美精品黄 |