• Stars
    star
    100
  • Rank 332,886 (Top 7 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

高仿微信文章悬浮球

JXWeChatFloatView

高仿微信文章悬浮球

头图.PNG

前言

微信在最新版本6.6.7,新加了一个文章悬浮球功能。当你正在阅读文章的时候,突然有好友发来了紧急消息,你需要立即回复。又或者你刚好路过小吃店,需要临时打开微信支付,等等临时中断阅读的情况。以前只有退出文章详情页面,处理完事情之后,再挨着挨着找到原来的文章。对于我们这种重度微信使用者来说,每次遭遇这种情况,真的很蛋疼。所以,当这个功能推出的事情,立马更新了最新版本,这个功能感觉就像遇到了知心人一样,用起来十分顺手。可以通过下面的动图感受一下 JXWeChatFloatView.gif

其实悬浮球的概念早就有了。比如360助手的流量监控球,iPhone自带的AssitiveTouch(就是那个可爱的小白球)等等。

仓库地址

Github地址喜欢就点颗❤️

核心技术点

体验过后,让人手痒痒,情不自禁得想要模仿一把。如果你的APP可以集成该功能,我觉得可以让你的APP逼格瞬间提升一个level。好了,下面让我们来一一解剖,微信文章悬浮球的核心技术点:

1.悬浮球的出现

当我们通过屏幕边缘手势pop视图的时候,右下角会有一个圆角提示图,跟着手势进度移动。 如何获取到UIScreenEdgePanGestureRecognizer的进度呢? 因为系统自带的interactivePopGestureRecognizer是被封装起来的,它的action我们无法挂钩拿到里面的手势进度。所以,需要另辟蹊径了。

  • 首先,让UINavigationController的delegate等于自己,然后让多个手势可以同时响应。
self.interactivePopGestureRecognizer?.delegate = self

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
  • 然后自己添加一个UIScreenEdgePanGestureRecognizer到UINavigationController上面,用于获取pop手势的进度。
let gesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleNavigationTransition(gesture:)))
gesture.edges = .left
self.view.addGestureRecognizer(gesture)

这样子,有两个UIScreenEdgePanGestureRecognizer可以同时响应,系统自带的依然保持原有逻辑不动,我们新增的用于获取pop手势进度,两者井水不犯河水,其乐融融。该技巧我的这篇文章也有使用iOS:一分钟集成主流APP个人资料页(如简书、微博等)

2.悬浮球全局置顶

既然悬浮球可以在悬浮在任何一个页面,必然是放在一个新的UIWindow上面。比如系统的键盘弹出的时候,就是一个UIRemoteKeyboardWindow在承载。 然后这个window的生命周期不依赖某一个页面,所以用单例实现比较好。这块代码比较分散,直接看源码就可以了解

3.事件响应

  • 悬浮UIWindow的事件传递 只要事件位置没有在圆球和右下角上,就不响应
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
    }
  • 右下角四分之一圆,事件响应 可以看到微信,只有当手指移动进右下角圆内,才能进行悬浮。而不是按着视图的frame来响应。 首先,通过UIBezierPath画一个四分之一圆,然后用CGPathcontains(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)
    }

对这块不太了解的同学,可以参考这篇文章。一篇搞定事件传递、响应者链条、hitTest和pointInside的使用

4.自定义转场动画

可以看到点击悬浮球打开的文章,是通过一个自定义转场动画实现的,从悬浮球的位置开始展开。 有许多文章都有讲解如何自定义转场动画,但是我推荐你看这篇文章几句代码快速集成自定义转场效果+ 全手势驱动

实现效果

JXWeChatFloatView-2.gif

总结

微信的悬浮球,用到的技术点相对比较多,代码也比较分散,如果你的APP要集成该功能,需要认真封装代码。 相对于如何实现,我认为如何设计好一个需求更重要。我在模仿的过程中,发现其中有许多细节的逻辑,彼此环环相扣,最终就呈现出了你正在使用的悬浮球功能。 都说程序员和产品经理是相爱相杀,在这里我要为该功能的产品经理点个赞👍

仓库地址

如果代码中有任何问题,否则你有任何疑问,都可以反馈给我,我将第一时间处理。 Github地址喜欢就点颗❤️

More Repositories

1

JXCategoryView

A powerful and easy to use category view (segmentedcontrol, segmentview, pagingview, pagerview, pagecontrol) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)
Objective-C
6,026
star
2

JXPagingView

类似微博主页、简书主页等效果。多页面嵌套,既可以上下滑动,也可以左右滑动切换页面。支持HeaderView悬浮、支持下拉刷新、上拉加载更多。
Objective-C
2,824
star
3

JXSegmentedView

A powerful and easy to use segmented view (segmentedcontrol, pagingview, pagerview, pagecontrol, categoryview) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)
Swift
2,596
star
4

JXPageListView

高仿闲鱼、转转、京东、中央天气预报等主流APP列表底部分页滚动视图
Objective-C
421
star
5

JXMarqueeView

A powerful and easy to use marquee view.
Swift
365
star
6

JXBottomSheetView

A useful and gesture interaction BottomSheetView!
Swift
256
star
7

JXTheme

A powerful and lightweight and customization theme/skin library for iOS 9+ in swift. 主题、换肤、暗黑模式
Swift
243
star
8

JXPatternLock

An easy-to-use, powerful, customizable pattern lock view in swift. 图形解锁/手势解锁 / 手势密码 / 图案密码 / 九宫格密码
Swift
219
star
9

JXMovableCellTableView

The custom tableView which can start moving the cell with a long press gesture.
Objective-C
188
star
10

JXPopupView

一个轻量级的自定义视图弹出框架
Swift
139
star
11

StackUI

StackUI just like SwiftUI
Swift
117
star
12

JXScratchView

一个万能的刮刮乐控件。无论是UILabel、UIImageView,还是自定义视图,只要是UIView都可以用来刮。代码简单,功能强大,你值得拥有!
Swift
111
star
13

JXBottomSheetTableView

A highly packaged, easy to use custom bottom sheet UITableView.
Swift
48
star
14

JXExcel

一个轻量级的表视图
Swift
31
star
15

JXTableViewZoomHeaderImageView

一般app的个人资料页面都会有个头图,并且随着上下滚动的时候,图片有个移动和缩放的效果。
Objective-C
29
star
16

ModelAdapter

Simple JSON Object mapping and SQLite3 written in Swift
Swift
26
star
17

JXCaptain

像美国队长一样威猛的应用调试工具箱!
Swift
22
star
18

JXFileBrowserController

The debug sandbox browser for sharing.
Swift
22
star
19

JXGradientKit

常用控件背景渐变色Kit
Swift
19
star
20

JXLayerAutoLayout

优雅的实现CALayer AutoLayout
Objective-C
19
star
21

SQLiteValueExtension

SQLiteValueExtension for SQLite.swift
Swift
14
star
22

JXParallaxCell

用于滚动scrollview的时候,cell中的图片,或者其他控件,有一个视差滚动的效果
Objective-C
14
star
23

JXTransition

自定义转场动画
Objective-C
11
star
24

JXBorderCellll

一个有边框的基类cell
Objective-C
11
star
25

JXInterview

Interview for iOSer
10
star
26

XPackage

自己常用的一些工具
Objective-C
4
star
27

30DaysChallenge

There may be a miracle happen if you insist 30 days challenge!
Objective-C
3
star
28

JXExampleImages

示例图片资源
2
star
29

JXKit

JXKit for iOS
Swift
1
star
30

OnePiece

Swift
1
star
31

JXRomanticAlbum

谁说程序员不浪漫?我们可以用代码表白!Who says programmers aren't romantic? We can use the code to express love!
Swift
1
star