swift 實(shí)現(xiàn)一個(gè)滑動(dòng)懸浮窗

直接上代碼


//
//  ZYFloatPlayerView.swift
//  SoChat
//
//  Created by APPLE on 2023/8/9.
//

import UIKit

class ZYFloatPlayerView: UIView {
    
    private var touchX : CGFloat = 0
    private var touchP : CGPoint = CGPoint(x: 0, y: 0)
    private var touchY : CGFloat = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}
/// 懸浮窗口功能實(shí)現(xiàn)
extension ZYFloatPlayerView {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        if let touch = touches.first {
            let touchPoint =  touch.location(in: self)
            touchX = touchPoint.x
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)
        if let touch = touches.first {
            let currentPosition =  touch.location(in: self)
            let offsetX = currentPosition.x - touchP.x - self.frame.size.width/2
            let offsetY = currentPosition.y - touchP.y - self.frame.size.height/2
            
          //移動(dòng)后的按鈕中心坐標(biāo)
            let centerX = self.center.x + offsetX
            var centerY = self.center.y + offsetY
            self.center = CGPoint(x: centerX, y: centerY)
            //父試圖的寬高
            let superViewWidth = self.superview!.frame.width
            let superViewHeight = self.superview!.frame.height
            ///
            
            let btnX = self.frame.origin.x
            let btnY = self.frame.origin.y
            let btnW = self.frame.size.width
            let btnH = self.frame.size.height
            
//            if centerY < GlobalNavAddStatusHeight + btnH/2 {
//                centerY = GlobalNavAddStatusHeight + btnH/2
//            }
//
//            if centerY > superViewHeight - GlobalTabBarAndSafeAreaBottomHeight - btnH/2 {
//                centerY = superViewHeight -  GlobalNavAddStatusHeight + btnH/2
//            }
            
            //x軸左右極限坐標(biāo)
            if btnX > superViewWidth {
                //按鈕右側(cè)越界
                let centerX = superViewWidth - btnW
                self.center = CGPoint(x: centerX, y: centerY )
            }else if (btnX < 0){
                //按鈕左側(cè)越界
                let centerX = btnW * 0.5
                self.center = CGPoint(x: centerX, y: centerY)
            }
            
            let judgeSuperViewHeight = superViewHeight - GlobalTabBarAndSafeAreaBottomHeight - btnH*0.5

            //y軸上下極限坐標(biāo)
            if btnY <= GlobalNavAddStatusHeight + btnH*0.5 {
                //按鈕頂部越界
//                centerY = btnH * 0.5
                let x = centerX
                let y = btnH * 0.5 + GlobalNavAddStatusHeight // 底部距離 tabbar + 安全距離
                self.center = CGPoint(x: x, y: y)
            } else if btnY > judgeSuperViewHeight {
                //按鈕底部越界
                let y = superViewHeight - btnH * 0.5
                let x = btnX + self.frame.size.height/2
                self.center = CGPoint(x:x, y:y)
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        let btnWidth = self.frame.size.width
        let btnHeight = self.frame.size.height
        let btnY = self.frame.origin.y
        let btnX = self.frame.origin.x
        
        let minDistance:CGFloat = 2

        //結(jié)束move的時(shí)候陕见,計(jì)算移動(dòng)的距離是>最低要求甥温,如果沒(méi)有,就調(diào)用按鈕點(diǎn)擊事件
        let isOverX = abs(btnX - touchX) > minDistance
        let isOverY = abs(btnY - touchY) > minDistance

        if isOverX || isOverY {
            //超過(guò)移動(dòng)范圍就不響應(yīng)點(diǎn)擊 - 只做移動(dòng)操作
            super.touchesCancelled(touches, with: event)
        }else{
            super.touchesEnded(touches, with: event)
        }

        if self.center.x >= self.superview!.frame.size.width/2 {
            UIView.animate(withDuration: 0.5) {
                let btnX = self.superview!.frame.size.width - btnWidth
                self.frame =  CGRect(x: btnX, y: btnY, width: btnWidth, height: btnHeight)
            }
        } else {
            UIView.animate(withDuration: 0.5) {
                let btnX:CGFloat = 0
                self.frame =  CGRect(x: btnX, y: btnY, width: btnWidth, height: btnHeight)
            }
        }
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斤程,一起剝皮案震驚了整個(gè)濱河市褪测,隨后出現(xiàn)的幾起案子瓦侮,更是在濱河造成了極大的恐慌升薯,老刑警劉巖涵卵,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浴栽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡轿偎,警方通過(guò)查閱死者的電腦和手機(jī)典鸡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坏晦,“玉大人萝玷,你說(shuō)我怎么就攤上這事∮⒃猓” “怎么了间护?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)挖诸。 經(jīng)常有香客問(wèn)我汁尺,道長(zhǎng),這世上最難降的妖魔是什么多律? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任痴突,我火速辦了婚禮,結(jié)果婚禮上狼荞,老公的妹妹穿的比我還像新娘辽装。我一直安慰自己,他們只是感情好相味,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拾积。 她就那樣靜靜地躺著,像睡著了一般丰涉。 火紅的嫁衣襯著肌膚如雪拓巧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天一死,我揣著相機(jī)與錄音肛度,去河邊找鬼。 笑死投慈,一個(gè)胖子當(dāng)著我的面吹牛承耿,可吹牛的內(nèi)容都是我干的冠骄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼加袋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凛辣!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起锁荔,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蟀给,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后阳堕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體跋理,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年恬总,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了前普。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壹堰,死狀恐怖拭卿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贱纠,我是刑警寧澤峻厚,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站谆焊,受9級(jí)特大地震影響惠桃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辖试,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一辜王、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罐孝,春花似錦呐馆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至改艇,卻和暖如春收班,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遣耍。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炮车,地道東北人舵变。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓酣溃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親纪隙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赊豌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容