国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

iOS粒子路徑移動(dòng)效果 iOS實(shí)現(xiàn)QQ拖動(dòng)效果

2020-07-26 02:44:40
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

粒子效果,QQ拖動(dòng)效果,實(shí)現(xiàn)很簡(jiǎn)單,具體代碼如下

一、圖示

這里寫(xiě)圖片描述

二、分析

我們要實(shí)現(xiàn)的如果如上面的圖示,那么我們可以按照下面的步驟操作:

第一步:我們的紅點(diǎn)其實(shí)是一個(gè)UIButton。創(chuàng)建一個(gè)BageValueView繼承自UIButton

第二步:初始化的時(shí)候,初始化控件,設(shè)置圓角,修改背景、文字顏色

第三步:添加手勢(shì)。在手勢(shì)的處理中我們,我們需要讓當(dāng)前控件隨著手指移動(dòng)而移動(dòng)。

第四步:控件一開(kāi)始創(chuàng)建的時(shí)候,其實(shí)有兩個(gè)圓,一個(gè)就是我們能夠拖動(dòng)的大圓,另外一個(gè)就是原始位置上會(huì)改變大小的圓。這一步驟中,主要就是創(chuàng)建這個(gè)小圓,它的初始參數(shù)和大圓一樣。
在手勢(shì)的處理中,根據(jù)兩圓的位置,來(lái)計(jì)算小圓半徑,當(dāng)兩圓的位置大于最大位置時(shí)候,小圓隱藏掉。

//獲取兩個(gè)圓之間的距離CGFloat distance = [self distanceWithSmallCircle:self.smallCircle bigCircle:self];if(distance<=MAX_DIST){//只有距離不超過(guò)最大距離才計(jì)算小圓半徑 //計(jì)算小圓的半徑 //小圓半徑最小的時(shí)候是MIN_RADIUS,這個(gè)時(shí)候兩個(gè)圓達(dá)到最大距離MAX_DIST //小圓半徑最大的時(shí)候是原始半徑,這個(gè)時(shí)候兩圓距離是0 //處于前面兩者之間的時(shí)候,小圓的半徑是:MIN_RADIUS + (原始半徑 - MIN_RADIUS)/MAX_DIST * (MAX_DIST - 當(dāng)前的距離) CGFloat smallR = self.bounds.size.width * 0.5; smallR = MIN_RADIUS + (MAX_DIST-distance) * (smallR-MIN_RADIUS)/MAX_DIST; //重新設(shè)置小圓的尺寸 self.smallCircle.bounds = CGRectMake(0, 0, smallR*2, smallR*2); //重新設(shè)置小圓的半徑 self.smallCircle.layer.cornerRadius = smallR;}else{//超過(guò)了最大距離 self.smallCircle.hidden = YES;}

第五步:創(chuàng)建大小圓之間的連接部分。連接部分我們需要?jiǎng)?chuàng)建一個(gè)形狀圖層(CAShapeLayer)――它可以根據(jù)一個(gè)路徑生成一個(gè)形狀。

路徑分析如下圖

根據(jù)上面我們需要?jiǎng)?chuàng)建一個(gè) ABCDA 其中DA和BC是曲線,控制點(diǎn)分別為O和P。

第六步:當(dāng)手勢(shì)結(jié)束的時(shí)候,我們需要判斷當(dāng)前兩圓的位置,如果小圓最大距離,那么復(fù)位。如果大于最大距離,那么添加一個(gè)銷(xiāo)毀動(dòng)畫(huà)。

三、代碼

2.1 BageValueView.m

//// BageValueView.m// 03_UIView78_粒子效果2//// Created by 杞文明 on 17/7/22.// Copyright © 2017年 杞文明. All rights reserved.//#import "BageValueView.h"#define MAX_DIST 80#define MIN_RADIUS 5@interface BageValueView()@property (nonatomic, weak) UIView *smallCircle;@property (nonatomic, weak) CAShapeLayer *shap;@end@implementation BageValueView-(void)awakeFromNib{ [self setUp];}-(instancetype)initWithFrame:(CGRect)frame{ if ( self = [super initWithFrame:frame] ) {  [self setUp]; } return self;}//形狀圖層-(CAShapeLayer*)shap{ if(_shap == nil){  //形狀圖層,它可以根據(jù)一個(gè)路徑生成一個(gè)形狀  CAShapeLayer *shap = [CAShapeLayer layer];  //設(shè)置形狀填充色  shap.fillColor = [UIColor redColor].CGColor;  _shap = shap;  //添加到最底層  [self.superview.layer insertSublayer:shap atIndex:0]; } return _shap;}//初始化-(void)setUp{ //設(shè)置圓角 self.layer.cornerRadius = self.bounds.size.width * 0.5; //設(shè)置背景文字顏色 [self setBackgroundColor:[UIColor redColor]]; [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; self.titleLabel.font = [UIFont systemFontOfSize:12]; //添加手勢(shì) UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan]; //添加小圓 UIView *smallCircle = [[UIView alloc]initWithFrame:self.frame]; smallCircle.backgroundColor = self.backgroundColor; smallCircle.layer.cornerRadius = self.layer.cornerRadius; self.smallCircle = smallCircle; //把小圓添加到父控件中,并且在大圓下面 [self.superview insertSubview:smallCircle belowSubview:self];}-(void)pan:(UIPanGestureRecognizer*)pan{ //獲取當(dāng)前點(diǎn) CGPoint currentP = [pan translationInView:self]; //移動(dòng) CGPoint center = self.center; center.x += currentP.x; center.y += currentP.y; self.center = center; //復(fù)位 [pan setTranslation:CGPointZero inView:self]; //獲取兩個(gè)圓之間的距離 CGFloat distance = [self distanceWithSmallCircle:self.smallCircle bigCircle:self]; if(distance<=MAX_DIST){//只有距離不超過(guò)最大距離才計(jì)算小圓半徑  //計(jì)算小圓的半徑  //小圓半徑最小的時(shí)候是MIN_RADIUS,這個(gè)時(shí)候兩個(gè)圓達(dá)到最大距離MAX_DIST  //小圓半徑最大的時(shí)候是原始半徑,這個(gè)時(shí)候兩圓距離是0  //處于前面兩者之間的時(shí)候,小圓的半徑是:MIN_RADIUS + (原始半徑 - MIN_RADIUS)/MAX_DIST * (MAX_DIST - 當(dāng)前的距離)  CGFloat smallR = self.bounds.size.width * 0.5;  smallR = MIN_RADIUS + (MAX_DIST-distance) * (smallR-MIN_RADIUS)/MAX_DIST;  //重新設(shè)置小圓的尺寸  self.smallCircle.bounds = CGRectMake(0, 0, smallR*2, smallR*2);  //重新設(shè)置小圓的半徑  self.smallCircle.layer.cornerRadius = smallR; }else{//超過(guò)了最大距離  self.smallCircle.hidden = YES;  [self.shap removeFromSuperlayer]; } //創(chuàng)建不規(guī)則路徑,其實(shí)就是連個(gè)圓之間連接的部分 //小圓不隱藏才創(chuàng)建 if(self.smallCircle.hidden == NO){  UIBezierPath *path = [self pathWithSmallCircle:self.smallCircle bigCircle:self];  self.shap.path = path.CGPath; } //當(dāng)手指松開(kāi)的時(shí)候 if (pan.state==UIGestureRecognizerStateEnded) {  //如果兩圓之間的距離小于最大距離,大圓復(fù)位  if (distance<MAX_DIST) {   //移除形狀圖層   [self.shap removeFromSuperlayer];   //添加一個(gè)彈性動(dòng)畫(huà)   [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.2 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{    //大圓復(fù)位    self.center = self.smallCircle.center;   } completion:^(BOOL finished) {    //小圓顯示    self.smallCircle.hidden = NO;   }];  } else {   //距離大于最大位置的時(shí)候,播放動(dòng)畫(huà),按鈕從父控件中刪除   //添加一個(gè)UIImageView 用來(lái)播放動(dòng)畫(huà)   UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds];   [self addSubview:imageV];   //添加圖片   NSMutableArray *imageArray = [NSMutableArray array];   for (int i=1; i<=8; i++) {    NSString *imageName = [NSString stringWithFormat:@"%d",i];    UIImage *image = [UIImage imageNamed:imageName];    [imageArray addObject:image];   }   imageV.animationImages = imageArray;   //設(shè)置動(dòng)畫(huà)時(shí)長(zhǎng)   [imageV setAnimationDuration:1];   //開(kāi)始動(dòng)畫(huà)   [imageV startAnimating];   //一秒鐘后.把當(dāng)前的按鈕從父控件當(dāng)中移.   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{    [self removeFromSuperview];   });  } }}//計(jì)算兩個(gè)圓之間的距離 使用勾股定理:兩直角邊的平方和等于斜邊的平方- (CGFloat)distanceWithSmallCircle:(UIView *)smallCircle bigCircle:(UIView *)bigCircle{ //X軸上的偏移量(就是x1-x2的值) CGFloat offsetX = bigCircle.center.x - smallCircle.center.x; //y軸上的偏移量(就是y1-y2的值) CGFloat offsetY = bigCircle.center.y - smallCircle.center.y; return sqrt(offsetX*offsetX + offsetY*offsetY);}//根據(jù)兩個(gè)圓設(shè)置一個(gè)不規(guī)的路徑- (UIBezierPath *)pathWithSmallCircle:(UIView *)smallCircle bigCircle:(UIView *)bigCircle{ CGFloat x1 = smallCircle.center.x; CGFloat y1 = smallCircle.center.y; CGFloat x2 = bigCircle.center.x; CGFloat y2 = bigCircle.center.y; CGFloat d = [self distanceWithSmallCircle:smallCircle bigCircle:self]; if (d <= 0) {  return nil; } CGFloat cosθ = (y2 - y1) / d; CGFloat sinθ = (x2 - x1) / d; CGFloat r1 = smallCircle.bounds.size.width * 0.5; CGFloat r2 = bigCircle.bounds.size.width * 0.5; CGPoint pointA = CGPointMake(x1 - r1 * cosθ, y1 + r1 * sinθ); CGPoint pointB = CGPointMake(x1 + r1 * cosθ, y1 - r1 * sinθ); CGPoint pointC = CGPointMake(x2 + r2 * cosθ, y2 - r2 * sinθ); CGPoint pointD = CGPointMake(x2 - r2 * cosθ, y2 + r2 * sinθ); CGPoint pointO = CGPointMake(pointA.x + d * 0.5 * sinθ, pointA.y + d * 0.5 * cosθ); CGPoint pointP = CGPointMake(pointB.x + d * 0.5 * sinθ, pointB.y + d * 0.5 * cosθ); UIBezierPath *path = [UIBezierPath bezierPath]; //AB [path moveToPoint:pointA]; [path addLineToPoint:pointB]; //BC(曲線) [path addQuadCurveToPoint:pointC controlPoint:pointP]; //CD [path addLineToPoint:pointD]; //DA(曲線) [path addQuadCurveToPoint:pointA controlPoint:pointO]; return path;}//清空高亮狀態(tài)-(void)setHighlighted:(BOOL)highlighted{}@end

2.2 ViewController.m

//// ViewController.m// 03_UIView78_粒子效果2//// Created by 杞文明 on 17/7/22.// Copyright © 2017年 杞文明. All rights reserved.//#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //讓View在顯示時(shí)不要把Autoresizing轉(zhuǎn)成自動(dòng)布局 self.view.translatesAutoresizingMaskIntoConstraints = NO;}@end

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 丹阳市| 介休市| 即墨市| 龙井市| 浏阳市| 曲水县| 明溪县| 乾安县| 榆社县| 博爱县| 闽清县| 门头沟区| 新疆| 锡林浩特市| 田阳县| 海南省| 清水县| 沛县| 泾阳县| 开鲁县| 桐城市| 普安县| 玛多县| 长海县| 白沙| 沙田区| 宁安市| 文山县| 巫山县| 望城县| 南开区| 洪湖市| 桐庐县| 阿勒泰市| 宜春市| 朝阳区| 义乌市| 惠东县| 阿鲁科尔沁旗| 阿瓦提县| 宜阳县|