最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

IOS設(shè)置QQ小紅點消除的方法(一鍵退朝)

 更新時間:2016年01月28日 16:31:36   作者:阿曌  
這篇文章主要介紹了IOS設(shè)置QQ小紅點消除的方法(一鍵退朝),對ios設(shè)置小紅點消除相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧

QQ上黏黏的小紅點很好玩有木有,于是自己也想實現(xiàn)一番,看到iOS實現(xiàn)的人比較少,Android的比較多,于是這個就用iOS來實現(xiàn)哈~

效果圖:

這里寫圖片描述 

調(diào)試圖:

這里寫圖片描述

其實從實現(xiàn)來講,我是先實現(xiàn)第二張圖的效果的。

腳本之家小編給大家說下實現(xiàn)思路

1.了解原理,以及如何繪制“黏黏”形狀(即繪制兩圓加兩條貝塞爾曲線)。

2.新建UIView(AZMetaBallCanvas),作為單獨畫布用來繪制“黏黏”形狀,用程序?qū)崿F(xiàn)算法,并繪制出來。

3.給畫布(AZMetaBallCanvas)添加attach:(UIView *)方法,并添加手勢監(jiān)聽,重繪,使得任意 view 都能夠被在畫布上擁有“黏黏”效果。

4.根據(jù)連心線的距離加上判斷是否要斷開,用戶手指離開時也要根據(jù)距離來判斷是爆炸動畫還是回彈動畫。

詳細(xì)過程

首先必須要了解小紅點拖拽的過程形狀是什么,其實就是類似元球效果(MetaBall)。仔細(xì)觀察可分析發(fā)現(xiàn),就是兩個大小不一樣的圓加上兩條貝塞爾曲線構(gòu)成的。

這里寫圖片描述

關(guān)于算法部分,我已經(jīng)分解成了另外一篇博文,強烈建議不清楚該形狀是怎么畫出來的同學(xué)先看一下《【算法分析】QQ“一鍵退朝”之詳細(xì)計算方法》

1.繪制拖拽

既然怎么求坐標(biāo)點畫出來我們已經(jīng)知道了,現(xiàn)在就可以去實現(xiàn)了。

首先新建一個“畫布”,繼承自UIView

//AZMetaBallCanvas.h
@interface AZMetaBallCanvas : UIView
@property(nonatomic,strong) Circle *centerCircle;
@property(nonatomic,strong) Circle *touchCircle;
@end

Circle為自定義實體類,里面定義了一些圓的基本屬性,如圓心坐標(biāo)、半徑等。

為什么要新建一個畫布?

因為小紅點是能夠全屏拖動的,別看QQ上它存在某一行Cell,但其實你可以把它拉到別的Cell上去,這就需要給小紅點足夠的位置來繪制,就干脆新建一個畫布專門用來繪制小紅點的動作好了。

AZMetaBallCanvas目前包含兩個屬性,兩個圓,一個中心圓,一個觸摸圓,按照需求來看,中心圓應(yīng)該是位置不變的,觸摸圓會跟隨手指觸摸屏幕的位置而改變,后面需要在兩個圓之間畫上貝塞爾曲線來構(gòu)成元球效果。

接下來開始寫AZMetaBallCanvas的實現(xiàn)

//AZMetaBallCanvas.m
#define RADIUS 40.0
@interface AZMetaBallCanvas() {
UIBezierPath *_path;
CGPoint _touchPoint;
}
@end
@implementation AZMetaBallCanvas
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
NSLog(@"initWithCorder");
if (self) {
[self initData];
}
return self;
}
- (void)initData {
_touchCircle = [Circle initWithcenterPoint:self.center radius:RADIUS];
_centerCircle = [Circle initWithcenterPoint:self.center radius:RADIUS];
_touchPoint = self.center;
NSLog(@"self.center (%f, %f)", self.center.x, self.center.y);
}
@end

先初始化兩個圓的位置,默認(rèn)在View的中心,并在init、initWithFrame、initWithCoder等父類構(gòu)造函數(shù)中加入自定義初始化方法initData。

重寫繪制方法

如同Android中的onDraw(),iOS中的drawRect能夠被重寫繪制,然后調(diào)用[view setNeedsDisplay]來通知重繪。

- (void)drawRect:(CGRect)rect {
_path = [[UIBezierPath alloc] init];

[self drawCenterCircle];

[self drawTouchCircle:_touchPoint];

[self drawBezierCurveWithCircle1:_centerCircle Circle2:_touchCircle];
}

如同算法分析中所講,在繪制的時候,我們只需要繪制兩個圓(drawCenterCircle、drawTouchCircle)和連接兩圓的貝塞爾曲線(drawBezierCurve),算法其實就是照抄《【算法分析】QQ“一鍵退朝”之詳細(xì)計算方法》

iOS自帶貝塞爾曲線UIBezierPath,其自帶畫圓方法addArcWithCenter: radius: startAngle: endAngle: clockwise:,所以我們只要調(diào)用就好啦!

#pragma mark draw circle --- 畫圓
- (void) drawCenterCircle {
[self drawCircle:_path circle:_centerCircle];
}
- (void) drawTouchCircle:(CGPoint)center {
_touchCircle.centerPoint = center;
[self drawCircle:_path circle:_touchCircle];
}
- (void)drawCircle:(UIBezierPath *)path circle:(Circle *)circle {
[_path addArcWithCenter:circle.centerPoint radius:circle.radius startAngle:0 endAngle:360 clockwise:true];
[_path fill];
[_path stroke];
[_path removeAllPoints];
}

#pragma mark draw curve --- 畫貝塞爾曲線
- (void)drawBezierCurveWithCircle1:(Circle *)circle1 Circle2:(Circle *)circle2 {
float circle1_x = circle1.centerPoint.x;
float circle1_y = circle1.centerPoint.y;
float circle2_x = circle2.centerPoint.x;
float circle2_y = circle2.centerPoint.y;
//連心線的長度
float d = sqrt(powf(circle1_x - circle2_x, 2) + powf(circle1_y - circle2_y, 2));
//連心線x軸的夾角
float angle1 = atan((circle2_y - circle1_y) / (circle1_x - circle2_x));
//連心線和公切線的夾角
float angle2 = asin((circle1.radius - circle2.radius) / d);
//切點到圓心和x軸的夾角
float angle3 = M_PI_2 - angle1 - angle2;
float angle4 = M_PI_2 - angle1 + angle2;
float offset1_X = cos(angle3) * circle1.radius;
float offset1_Y = sin(angle3) * circle1.radius;
float offset2_X = cos(angle3) * circle2.radius;
float offset2_Y = sin(angle3) * circle2.radius;
float offset3_X = cos(angle4) * circle1.radius;
float offset3_Y = sin(angle4) * circle1.radius;
float offset4_X = cos(angle4) * circle2.radius;
float offset4_Y = sin(angle4) * circle2.radius;
float p1_x = circle1_x - offset1_X;
float p1_y = circle1_y - offset1_Y;
float p2_x = circle2_x - offset2_X;
float p2_y = circle2_y - offset2_Y;
float p3_x = circle1_x + offset3_X;
float p3_y = circle1_y + offset3_Y;
float p4_x = circle2_x + offset4_X;
float p4_y = circle2_y + offset4_Y;
CGPoint p1 = CGPointMake(p1_x, p1_y);
CGPoint p2 = CGPointMake(p2_x, p2_y);
CGPoint p3 = CGPointMake(p3_x, p3_y);
CGPoint p4 = CGPointMake(p4_x, p4_y);
CGPoint p1_center_p4 = CGPointMake((p1_x + p4_x) / 2, (p1_y + p4_y) / 2);
CGPoint p2_center_p3 = CGPointMake((p2_x + p3_x) / 2, (p2_y + p3_y) / 2);
[self drawBezierCurveStartAt:p1 EndAt:p2 controlPoint:p2_center_p3];
[self drawLineStartAt:p2 EndAt:p4];
[self drawBezierCurveStartAt:p4 EndAt:p3 controlPoint:p1_center_p4];
[self drawLineStartAt:p3 EndAt:p1];
[_path moveToPoint:p1];
[_path closePath];
[_path stroke];
}

2.監(jiān)聽手勢

簡單版

最簡單的其實就是直接在AZMetaBallCanvas中重寫touchXXX等一系列方法,然后在其中調(diào)用setNeedsDisplay通知UIView重繪。

#pragma mark touch event
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
_touchPoint = [touch locationInView:self];
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
_touchPoint = [touch locationInView:self];
[self setNeedsDisplay];
}

現(xiàn)在其實差不多第二張圖的效果已經(jīng)出來了,差的就是更改兩圓的半徑方法。

這里寫圖片描述

改變半徑的方法就非常簡單了

#pragma 改變半徑
-(void)changeCenterCircleRadiusTo:(float)radius {
_centerCircle.radius = radius;
[self setNeedsDisplay];
}
-(void)changeTouchCircleRadiusTo:(float)radius {
_touchCircle.radius = radius;
[self setNeedsDisplay];
}

普通版

根據(jù)現(xiàn)象發(fā)現(xiàn),我們需要通過拖拽小紅點來移動它,而不是我們手指點哪,小紅點就在哪,所以我們需要給小紅點增加手勢監(jiān)聽,而不是“畫布”。

于是我們改為在畫布添加方法- (void)attach:(UIView *)item;,然后再給傳入的view添加Pan手勢。

- (void)attach:(UIView *)item {
UIPanGestureRecognizer *drag = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(drag:)];
item.userInteractionEnabled = YES;
[item addGestureRecognizer:drag];
}
- (void)drag:(UIPanGestureRecognizer *)recognizer {
//得到觸摸點
_touchPoint = [recognizer locationInView:self];
//得到觸摸的view
UIView *touchView = recognizer.view;
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:{
//touch開始:在畫布上繪制一個touchView的副本
//...此部分參看源碼
break;
}
case UIGestureRecognizerStateChanged:{
//移動中:記錄觸摸位置,更改touchView和touchCircle的坐標(biāo)位置
[self resetTouchCenter:_touchPoint];
break;
}
case UIGestureRecognizerStateEnded: {
//touch結(jié)束:根據(jù)連心線長度判斷是執(zhí)行爆炸動畫還是彈簧動畫
//...此部分參看源碼
break;
}
default:
break;
}
[self setNeedsDisplay]; //重繪
}

以上內(nèi)容是小編給大家介紹的IOS設(shè)置QQ小紅點消除的方法(一鍵退朝),希望對大家有所幫助。

相關(guān)文章

  • iOS 底層alloc init new 源碼流程示例分析

    iOS 底層alloc init new 源碼流程示例分析

    這篇文章主要為大家介紹了iOS 底層alloc init new 源碼流程示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • iOS 12+ 中檢測網(wǎng)絡(luò)訪問的方法

    iOS 12+ 中檢測網(wǎng)絡(luò)訪問的方法

    這篇文章主要介紹了iOS 12+ 中檢測網(wǎng)絡(luò)訪問的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 針對iOS10新增Api的詳細(xì)研究

    針對iOS10新增Api的詳細(xì)研究

    這篇文章主要針對iOS10新增Api進(jìn)行詳細(xì)研究,基于Api層面,著重看一些具體用法所做的筆記,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS開發(fā)中#import、#include和@class的區(qū)別解析

    iOS開發(fā)中#import、#include和@class的區(qū)別解析

    這篇文章主要介紹了iOS開發(fā)中#import、#include和@class的區(qū)別解析,非常不錯,具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧
    2016-08-08
  • IOS如何替換電話號碼中間4位為

    IOS如何替換電話號碼中間4位為"-"符號

    這篇文章主要為大家詳細(xì)介紹了IOS如何替換電話號碼中間4位為-符號的方法,感興趣的小伙伴們可以參考一下
    2016-07-07
  • IOS中各種手勢操作實例代碼

    IOS中各種手勢操作實例代碼

    IOS中手勢操作一般是 UIGestureRecognizer 類的幾個手勢子類去實現(xiàn),一般我們用到的手勢就這么5種,具體哪幾種大家通過本文學(xué)習(xí)吧,本文重點給大家介紹IOS中各種手勢操作實例代碼,一起看看吧
    2017-03-03
  • iOS 11 UINavigationItem 去除左右間隙的方法

    iOS 11 UINavigationItem 去除左右間隙的方法

    本篇文章主要介紹了iOS 11 UINavigationItem 去除左右間隙的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • iOS自定義UIButton點擊動畫特效

    iOS自定義UIButton點擊動畫特效

    這篇文章主要為大家詳細(xì)介紹了iOS自定義UIButton點擊動畫特效,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • 兩種iOS隱藏導(dǎo)航欄的正確方法

    兩種iOS隱藏導(dǎo)航欄的正確方法

    這篇文章主要為大家詳細(xì)介紹了iOS導(dǎo)航欄的正確隱藏方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • iOS中生成指定大小、指定顏色的二維碼和條形碼方法詳解

    iOS中生成指定大小、指定顏色的二維碼和條形碼方法詳解

    本文主要介紹了iOS中生成指定大小、指定顏色的二維碼和條形碼的具體實現(xiàn)方法,具有一定的參考價值,下面跟著小編一起來看下吧
    2016-12-12

最新評論

会同县| 佛教| 喀喇沁旗| 丰城市| 泰安市| 郁南县| 新源县| 锦州市| 舟山市| 普兰县| 吉林市| 金门县| 钟祥市| 武川县| 洪泽县| 太和县| 安阳市| 宁化县| 鄂尔多斯市| 喀喇沁旗| 锦屏县| 巫溪县| 夏津县| SHOW| 高台县| 隆安县| 武宁县| 商河县| 织金县| 嘉黎县| 普宁市| 孝感市| 仪陇县| 玉树县| 博野县| 弋阳县| 五大连池市| 云安县| 北宁市| 安康市| 宁国市|