方便的 UIButton 悬浮效果

页面中经常遇到需要悬浮展示并且可以随手势移动的按钮,简单实现了一个。
思路就是继承 UIButton 类,然后重写拖拽方法 .touchDragInside

    addTarget(self, action: #selector(dragMoving(btn: event:)), for: .touchDragInside)
    addTarget(self, action: #selector(dragEnd(btn: event:)), for: .touchUpInside)

因为 .touchDragInside 是在手势移动过程中会不断的触发,在移动结束的手指抬起时才会触发 .touchUpInside

需要每次移动触发后获取到当前的 point

guard let touch = event.allTouches?.first else {
            print("⚠️ 无法获取 Touch ⚠️ ")
            return
        }
        
var point = touch.location(in: superview)

获取到后把 btn.center 设置为 point 所在点即可

一般会设置视图悬浮显示的区域为贴边显示,所以在滑动结束时需要重新设置下 point 的位置
不足屏幕的一半就贴在左边,否则贴在右边

 let btnx = btn.frame.size.width / 2
 if x <= btnx {
    point.x = btnx 
 }

if x >= (superview?.bounds.size.width)! - btnx {
    point.x = (superview?.bounds.size.width)! - btnx
}

由于 .touchUpInside 事件需要同时处理拖拽的结束和点击事件,所以需要每次在拖动结束后判断用户的意图是拖动视图还是点击视图,因为用户在点击的时候手指也可能在屏幕上滑动,在这里根据视图的位移来判断,定为上下左右位移超过 5px 则认为用户在进行拖动操作,否则是点击。

var p_start: CGPoint? //获取开始点击的初始位置
var isDrag: Bool?    

@objc func dragMoving(btn: UIButton, event: UIEvent) -> Void {

        var point = touch.location(in: superview)
        
        if !isDrag! { 
            p_start = point
            isDrag = true
        }
}

上面也提及到了,.touchDragInside 会随手势移动而不断的触发,我们只需要记录开始的 point 就好

在拖动结束时判断位置距离

@objc func dragEnd(btn: UIButton, event: UIEvent) -> Void {
        isDrag = false
        
        var point = touch.location(in: superview)
        let p_end = point
        
         if abs(p_start!.x - p_end.x) < 5 && abs(p_start!.y - p_end.y) < 5 {
            if (clicked != nil) {
                clicked!()
            }
        }
}

一般不需要视图紧贴屏幕边缘,会设置一个 margin 来控制离屏幕边际距离。

 let kEdgeMargin: CGFloat = 5.0  //视图与屏幕距离最小距离

最终效果:


模拟器效果

完整代码:FlyBtn

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容