iOS高仿微信文章懸浮球功能

前言
微信在最新版本6.6.7,新加了一個(gè)文章懸浮球功能。當(dāng)你正在閱讀文章的時(shí)候,突然有好友發(fā)來(lái)了緊急消息,你需要立即回復(fù)。又或者你剛好路過(guò)小吃店,需要臨時(shí)打開(kāi)微信支付,等等臨時(shí)中斷閱讀的情況。以前只有退出文章詳情頁(yè)面,處理完事情之后,再挨著挨著找到原來(lái)的文章。對(duì)于我們這種重度微信使用者來(lái)說(shuō),每次遭遇這種情況。所以,當(dāng)這個(gè)功能推出的事情,立馬更新了最新版本,這個(gè)功能感覺(jué)就像遇到了知心人一樣,用起來(lái)十分順手??梢酝ㄟ^(guò)下面的動(dòng)圖感受一下

其實(shí)懸浮球的概念早就有了。比如360助手的流量監(jiān)控球,iPhone自帶的AssitiveTouch(就是那個(gè)可愛(ài)的小白球)等等。
倉(cāng)庫(kù)地址
Github地址 喜歡就點(diǎn)顆:heart:
核心技術(shù)點(diǎn)
體驗(yàn)過(guò)后,讓人手癢癢,情不自禁得想要模仿一把。如果你的APP可以集成該功能,我覺(jué)得可以讓你的APP逼格瞬間提升一個(gè)level。好了,下面讓我們來(lái)一一解剖,微信文章懸浮球的核心技術(shù)點(diǎn):
1.懸浮球的出現(xiàn)
當(dāng)我們通過(guò)屏幕邊緣手勢(shì)pop視圖的時(shí)候,右下角會(huì)有一個(gè)圓角提示圖,跟著手勢(shì)進(jìn)度移動(dòng)。
如何獲取到UIScreenEdgePanGestureRecognizer的進(jìn)度呢?
因?yàn)橄到y(tǒng)自帶的interactivePopGestureRecognizer是被封裝起來(lái)的,它的action我們無(wú)法掛鉤拿到里面的手勢(shì)進(jìn)度。所以,需要另辟蹊徑了。
首先,讓UINavigationController的delegate等于自己,然后讓多個(gè)手勢(shì)可以同時(shí)響應(yīng)。
self.interactivePopGestureRecognizer?.delegate = self
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}然后自己添加一個(gè)UIScreenEdgePanGestureRecognizer到UINavigationController上面,用于獲取pop手勢(shì)的進(jìn)度。
let gesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleNavigationTransition(gesture:))) gesture.edges = .left self.view.addGestureRecognizer(gesture)
這樣子,有兩個(gè)UIScreenEdgePanGestureRecognizer可以同時(shí)響應(yīng),系統(tǒng)自帶的依然保持原有邏輯不動(dòng),我們新增的用于獲取pop手勢(shì)進(jìn)度,兩者井水不犯河水,其樂(lè)融融。
2.懸浮球全局置頂
既然懸浮球可以在懸浮在任何一個(gè)頁(yè)面,必然是放在一個(gè)新的UIWindow上面。比如系統(tǒng)的鍵盤(pán)彈出的時(shí)候,就是一個(gè)UIRemoteKeyboardWindow在承載。
然后這個(gè)window的生命周期不依賴(lài)某一個(gè)頁(yè)面,所以用單例實(shí)現(xiàn)比較好。這塊代碼比較分散,直接看源碼就可以了解
3.事件響應(yīng)
懸浮UIWindow的事件傳遞
只要事件位置沒(méi)有在圓球和右下角上,就不響應(yīng)
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let roundEntryViewPoint = self.convert(point, to: roundEntryView)
if roundEntryView.point(inside: roundEntryViewPoint, with: event) == true {
return true
}
let collectViewPoint = self.convert(point, to: collectView)
if collectView.point(inside: collectViewPoint, with: event) == true {
return true
}
return false
}右下角四分之一圓,事件響應(yīng)
可以看到微信,只有當(dāng)手指移動(dòng)進(jìn)右下角圓內(nèi),才能進(jìn)行懸浮。而不是按著視圖的frame來(lái)響應(yīng)。
首先,通過(guò)UIBezierPath畫(huà)一個(gè)四分之一圓,然后用CGPath的contains(point)方法判斷。
func updateBGLayerPath(isSmall: Bool) {
var ratio:CGFloat = 1
if !isSmall {
ratio = 1.3
}
let path = UIBezierPath()
path.move(to: CGPoint(x: viewSize.width, y: (1 - ratio)*viewSize.height))
path.addLine(to: CGPoint(x: viewSize.width, y: viewSize.height))
path.addLine(to: CGPoint(x: (1 - ratio)*viewSize.width, y: viewSize.height))
path.addArc(withCenter: CGPoint(x: viewSize.width, y: viewSize.height), radius: viewSize.width*ratio, startAngle: CGFloat(Double.pi), endAngle: CGFloat(Double.pi*3/2), clockwise: true)
path.close()
bgLayer.path = path.cgPath
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return bgLayer.path!.contains(point)
}4.自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
可以看到點(diǎn)擊懸浮球打開(kāi)的文章,是通過(guò)一個(gè)自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)實(shí)現(xiàn)的,從懸浮球的位置開(kāi)始展開(kāi)。
有許多文章都有講解如何自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà),但是我推薦你看這篇文章 幾句代碼快速集成自定義轉(zhuǎn)場(chǎng)效果+ 全手勢(shì)驅(qū)動(dòng)
實(shí)現(xiàn)效果

總結(jié)
微信的懸浮球,用到的技術(shù)點(diǎn)相對(duì)比較多,代碼也比較分 散,如果你的APP要集成該功能,需要認(rèn)真封裝代碼。
相對(duì)于如何實(shí)現(xiàn),我認(rèn)為如何設(shè)計(jì)好一個(gè)需求更重要。我在模仿的過(guò)程中,發(fā)現(xiàn)其中有許多細(xì)節(jié)的邏輯,彼此環(huán)環(huán)相扣,最終就呈現(xiàn)出了你正在使用的懸浮球功能。
都說(shuō)程序員和產(chǎn)品經(jīng)理是相愛(ài)相殺,在這里我要為該功能的產(chǎn)品經(jīng)理點(diǎn)個(gè)贊
倉(cāng)庫(kù)地址
如果代碼中有任何問(wèn)題,否則你有任何疑問(wèn),都可以反饋給我,我將第一時(shí)間處理。
Github地址 喜歡就點(diǎn)顆:heart:
總結(jié)
以上所述是小編給大家介紹的iOS高仿微信文章懸浮球功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
IOS 使用NSAssert()和NSParameterAssert調(diào)試程序
這篇文章主要介紹了IOS 使用NSAssert()和NSParameterAssert調(diào)試程序的相關(guān)資料,需要的朋友可以參考下2017-06-06
iOS開(kāi)發(fā)中UIPopoverController的使用詳解
這篇文章主要介紹了iOS開(kāi)發(fā)中UIPopoverController的使用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-11-11
iOS實(shí)現(xiàn)百度外賣(mài)頭像波浪的效果
對(duì)于現(xiàn)在很多人來(lái)說(shuō),叫外賣(mài)就成了不可或缺的習(xí)慣。某日瞬間發(fā)現(xiàn)百度外賣(mài)的APP波浪效果很是吸引人,相比較其他的外賣(mài)APP,顏值略高些.(淘寶也有波浪的效果),遂就思考如何實(shí)現(xiàn)這種"浪"的效果,下面來(lái)一起看看。2016-08-08
iOS 二維碼掃描相關(guān)功能實(shí)現(xiàn)
這篇文章主要介紹了iOS 二維碼掃描相關(guān)功能實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
iOS中UIActivityIndicatorView的用法及齒輪等待動(dòng)畫(huà)實(shí)例
UIActivityIndicatorView活動(dòng)指示器最常見(jiàn)的用法便是用來(lái)制作那個(gè)程序中的齒輪轉(zhuǎn)動(dòng)的等待效果,接下來(lái)我們回來(lái)簡(jiǎn)單整理iOS中UIActivityIndicatorView的用法及齒輪等待動(dòng)畫(huà)實(shí)例:2016-05-05
iOS10 widget實(shí)現(xiàn)3Dtouch 彈出菜單
這篇文章主要介紹了 iOS10 widget實(shí)現(xiàn)3Dtouch 彈出菜單的相關(guān)資料,需要的朋友可以參考下2016-12-12
詳解使用Xcode進(jìn)行iOS設(shè)備無(wú)線(xiàn)調(diào)試
這篇文章主要介紹了詳解使用Xcode進(jìn)行iOS設(shè)備無(wú)線(xiàn)調(diào)試,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12

