swift 實(shí)現(xiàn)圓形區(qū)域拖動(dòng)

寫在前面的:

實(shí)現(xiàn)限制在圓形區(qū)域拖動(dòng)眷篇,雖然邏輯也很簡(jiǎn)單例诀,但是調(diào)試起來還挺費(fèi)心思的朽肥!…… 這里將我自己的經(jīng)驗(yàn)寫下來菇民,供需要的人參考尽楔!

最終效果:

動(dòng)圖效果

實(shí)現(xiàn)思路:

  • 實(shí)現(xiàn)小圓拖動(dòng)
  • 限制拖動(dòng)范圍

實(shí)現(xiàn)小圓拖動(dòng):

實(shí)現(xiàn)小圓拖動(dòng)的邏輯比較簡(jiǎn)單投储,給小圓添加拖動(dòng)手勢(shì)就可以了!...
為了簡(jiǎn)單起見(偷懶的借口^_^)阔馋,這里直接用 UIButton 通過設(shè)置圓角(高度的一半玛荞,以下的圓形拖動(dòng)區(qū)域也是一樣的做法)

var circle: UIView! // 定義【圓形】區(qū)域
var button: UIButton! // 定義【拖動(dòng)】按鈕

設(shè)置圓角以及添加拖動(dòng)手勢(shì)

// 添加【拖動(dòng)】按鈕
button = UIButton(frame: CGRect(x: origin.x - bRadius, y: origin.y - bRadius, width: bRadius * 2, height: bRadius * 2))
button.setTitle("測(cè)試", for: .normal)
button.backgroundColor = UIColor.orange  // 設(shè)置背景色
button.layer.cornerRadius = bRadius  // 設(shè)置圓角半徑
        
let pan = UIPanGestureRecognizer(target: self, action: #selector(dragButton))  // 定義【拖動(dòng)】手勢(shì)
button.addGestureRecognizer(pan)  // 添加【拖動(dòng)】手勢(shì)

定義拖動(dòng)手勢(shì)handler

@objc func dragButton(_ pan: UIPanGestureRecognizer) {
    let center = pan.location(in: pan.view!.superview)
    
    switch pan.state {
    
    case .changed:
        let newCenter = dragLimitInCircle(target: center, origin: origin, radius: cRadius)    // 限制在【圓形】上拖動(dòng)
        button.center = newCenter  // 設(shè)置【拖動(dòng)】按鈕 中心點(diǎn)位置
        
    default:
        break
    }
}

限制拖動(dòng)范圍:

繪制大圓拖動(dòng)限制區(qū)域(這里同樣通過設(shè)置圓角的方法實(shí)現(xiàn)!)

// 添加【圓形】區(qū)域
circle = UIView(frame: CGRect(x: origin.x - cRadius, y: origin.y - cRadius, width: cRadius * 2, height: cRadius * 2))
circle.backgroundColor = UIColor.blue  // 設(shè)置背景色
circle.layer.cornerRadius = cRadius  // 設(shè)置圓角半徑
view.addSubview(circle)  // 添加【圓形】區(qū)域 到【主視圖】

限制在圓形區(qū)域里面拖動(dòng)

// 限制【圓形】區(qū)域拖動(dòng) 方法
func dragLimitInCircle(target ePoint: CGPoint, origin oPoint: CGPoint, radius: CGFloat) -> CGPoint {
    var newPoint: CGPoint
    
    let x0 = ePoint.x - oPoint.x     // 坐標(biāo) X
    let y0 = ePoint.y - oPoint.y     // 坐標(biāo) Y
    let distance = sqrt(pow(x0, 2) + pow(y0, 2))  // 拖動(dòng)距離
    
    if distance <= radius - bRadius {
        newPoint = ePoint
    } else {
        let angle = atan(y0 / x0)
        var a: CGFloat = 1  //  定義【翻轉(zhuǎn)】系數(shù)
        
        if x0 < 0 {
            //  第二象限 | 第三象限
            a = -a
        }
        
        let x = oPoint.x + a * (radius - bRadius) * cos(angle)
        let y = oPoint.y + a * (radius - bRadius) * sin(angle)
        
        newPoint = CGPoint(x: x, y: y)
    }
    
    return newPoint
}

完整代碼:

//
//  DragInCircle.swift
//  UIKit-basic
//
//  Created by Qire_er on 2021/11/26.
//

import UIKit

class DragInCircleVC: UIViewController {
    
    var circle: UIView! // 定義【圓形】區(qū)域
    var button: UIButton! // 定義【拖動(dòng)】按鈕
    
    let dWidth = UIScreen.main.bounds.width  //【設(shè)備】寬度
    let dHeight = UIScreen.main.bounds.height  //【設(shè)備】高度
    let cRadius: CGFloat = 160 // 定義【圓形】區(qū)域 半徑
    let bRadius: CGFloat = 30 // 定義【拖動(dòng)】按鈕 半徑
    
    var origin: CGPoint {
        CGPoint(x: dWidth / 2, y: dHeight / 2)
    }    //  【原點(diǎn)】位置

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 添加【圓形】區(qū)域
        circle = UIView(frame: CGRect(x: origin.x - cRadius, y: origin.y - cRadius, width: cRadius * 2, height: cRadius * 2))
        circle.backgroundColor = UIColor.blue  // 設(shè)置背景色
        circle.layer.cornerRadius = cRadius  // 設(shè)置圓角半徑
        view.addSubview(circle)  // 添加【圓形】區(qū)域 到【主視圖】
        
        // 添加【拖動(dòng)】按鈕
        button = UIButton(frame: CGRect(x: origin.x - bRadius, y: origin.y - bRadius, width: bRadius * 2, height: bRadius * 2))
        button.setTitle("測(cè)試", for: .normal)
        button.backgroundColor = UIColor.orange  // 設(shè)置背景色
        button.layer.cornerRadius = bRadius  // 設(shè)置圓角半徑
        
        let pan = UIPanGestureRecognizer(target: self, action: #selector(dragButton))  // 定義【拖動(dòng)】手勢(shì)
        button.addGestureRecognizer(pan)  // 添加【拖動(dòng)】手勢(shì)

        view.addSubview(button)  // 添加【拖動(dòng)】按鈕 到【主視圖】
        
        view.backgroundColor = UIColor.white
    }
    
    @objc func dragButton(_ pan: UIPanGestureRecognizer) {
        let center = pan.location(in: pan.view!.superview)
        
        switch pan.state {
        
        case .changed:
            let newCenter = dragLimitInCircle(target: center, origin: origin, radius: cRadius)    // 限制在【圓形】上拖動(dòng)
            button.center = newCenter  // 設(shè)置【拖動(dòng)】按鈕 中心點(diǎn)位置
            
        default:
            break
        }
    }

    // 限制【圓形】區(qū)域拖動(dòng) 方法
    func dragLimitInCircle(target ePoint: CGPoint, origin oPoint: CGPoint, radius: CGFloat) -> CGPoint {
        var newPoint: CGPoint
        
        let x0 = ePoint.x - oPoint.x     // 坐標(biāo) X
        let y0 = ePoint.y - oPoint.y     // 坐標(biāo) Y
        let distance = sqrt(pow(x0, 2) + pow(y0, 2))  // 拖動(dòng)距離
        
        if distance <= radius - bRadius {
            newPoint = ePoint
        } else {
            let angle = atan(y0 / x0)
            var a: CGFloat = 1  //  定義【翻轉(zhuǎn)】系數(shù)
            
            if x0 < 0 {
                //  第二象限 | 第三象限
                a = -a
            }
            
            let x = oPoint.x + a * (radius - bRadius) * cos(angle)
            let y = oPoint.y + a * (radius - bRadius) * sin(angle)
            
            newPoint = CGPoint(x: x, y: y)
        }
        
        return newPoint
    }
}

(==完==)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呕寝,一起剝皮案震驚了整個(gè)濱河市勋眯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壁涎,老刑警劉巖凡恍,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異怔球,居然都是意外死亡嚼酝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門竟坛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闽巩,“玉大人,你說我怎么就攤上這事担汤∠芽纾” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵崭歧,是天一觀的道長隅很。 經(jīng)常有香客問我,道長率碾,這世上最難降的妖魔是什么叔营? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮所宰,結(jié)果婚禮上绒尊,老公的妹妹穿的比我還像新娘。我一直安慰自己仔粥,他們只是感情好婴谱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躯泰,像睡著了一般谭羔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斟冕,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天口糕,我揣著相機(jī)與錄音,去河邊找鬼磕蛇。 笑死景描,一個(gè)胖子當(dāng)著我的面吹牛十办,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播超棺,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼萍诱,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼赖钞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蒙谓,失蹤者是張志新(化名)和其女友劉穎发侵,沒想到半個(gè)月后崇猫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體点骑,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年让虐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紊撕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赡突,死狀恐怖对扶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惭缰,我是刑警寧澤浪南,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站漱受,受9級(jí)特大地震影響络凿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜昂羡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一喷众、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧紧憾,春花似錦、人聲如沸昌渤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膀息。三九已至般眉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間潜支,已是汗流浹背甸赃。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冗酿,地道東北人埠对。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓络断,卻偏偏與公主長得像,于是被迫代替她去往敵國和親项玛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子貌笨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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

  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料襟沮? 從這篇文章中你...
    hw1212閱讀 12,723評(píng)論 2 59
  • Quartz2D以及drawRect的重繪機(jī)制字?jǐn)?shù)1487 閱讀21 評(píng)論1 喜歡1一锥惋、什么是Quartz2D Q...
    PurpleWind閱讀 773評(píng)論 0 3
  • 前段時(shí)間項(xiàng)目中有個(gè)特殊的需求,折騰了好久开伏,覺得有必要總結(jié)一下膀跌。我自己寫了一個(gè)日歷控件,產(chǎn)品要求選中的日期要用圓形圖...
    Zed_X閱讀 1,428評(píng)論 1 1
  • * 按鈕 復(fù)選框固灵、折疊控件捅伤、漸變按鈕、幫助按鈕怎虫、圖像按鈕暑认、彈出按鈕、下拉按鈕大审、操作按鈕蘸际、單選按鈕、范圍按鈕徒扶、切換按...
    王滋溜閱讀 658評(píng)論 0 1
  • 原文鏈接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影閱讀 32,931評(píng)論 6 472