??先上圖:
| -動(dòng)圖.gif- | -靜態(tài)圖- |
|---|---|
溫度曲線圖.GIF
|
![]() 靜態(tài)圖.jpeg
|
本人的獲取觸摸時(shí),手指在iphone??屏幕上的位置 1、ios ~ 手指在view或window上的位置 x、y
2、【Touch:iOS判斷當(dāng)前點(diǎn)擊的位置是否在某個(gè)視圖上】
判斷是否觸摸touch了某個(gè)View(contentView)
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
// 手指觸摸 移動(dòng)
// iOS 怎么樣獲取手指在view上滑動(dòng)的起點(diǎn)坐標(biāo)與終點(diǎn)坐標(biāo)
UITouch *touch = touches.anyObject;
CGPoint point = [touch locationInView:self.progress_lineBackView];
NSLog(@"移動(dòng)中: 手指所在 折線圖??上的位置 point.X ==== %f,\n point.Y ==== %f", point.x, point.y);
/**
* locationView 如果傳入的是需要判斷視圖(self.blueView)的父視圖,
* CGRectContainsPoint則需要傳入需要判斷視圖(self.blueView)的frame,
* 否則不需要判斷父視圖,只需要判斷當(dāng)前子視圖,需傳入 子視圖的bounds,即self.progress_lineBackView.bounds。
*/
// 如果矩形不為null,或空,并且該點(diǎn)位于矩形內(nèi),返回YES,在范圍外面 返回NO
if (!CGRectContainsPoint(self.progress_lineBackView.frame, point)) {
NSLog(@"觸摸 錯(cuò)錯(cuò)錯(cuò)?");
} else {
NSLog(@"?? 觸摸 對了");
}
}
因?yàn)?,底層View是一個(gè)UITableView,在左右滑動(dòng)時(shí)(即point.x > point.y時(shí),暫時(shí)禁止tableview滑動(dòng),觸摸結(jié)束時(shí),恢復(fù)tableview的滑動(dòng))。
一、原理:
(1)先將紫色view創(chuàng)建出來,(40日,一天一個(gè)數(shù)據(jù),共40個(gè)),將紫色view分成40個(gè)色塊,每塊空白的色塊上面,在每個(gè)空白色塊上面,各畫出一個(gè)豎線,在這里我設(shè)置了豎線背景色的為半透明,之后滑到那個(gè)色塊的范圍時(shí),改變其上的豎線顏色;
(2)在淡藍(lán)色的view上創(chuàng)建一個(gè)CAShapeLayer(即,折線圖的父layer),在上面可以畫出折線圖,并將那一個(gè)個(gè)端點(diǎn)的坐標(biāo),保存到數(shù)組circleArray,方便之后,畫出小圓點(diǎn);
(3)最后就是上邊的提示框了,在某一個(gè)范圍內(nèi)移動(dòng)(改變其X軸的偏移量,和數(shù)據(jù))。
以上,GIF圖中,不同顏色的view或layer,一層層疊加覆蓋,最后將那幾個(gè)背景色設(shè)置為透明色
獲取觸摸屏幕時(shí)的坐標(biāo):
// iOS 怎么樣獲取手指在self.view上的坐標(biāo),
UITouch *touch = touches.anyObject;
CGPoint point = [touch locationInView:self.view];
系統(tǒng)的觸摸方法:(在這里,只是用了前三個(gè),即,開始、移動(dòng)、結(jié)束,三個(gè)步驟)
// 開始觸摸
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 移動(dòng)
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 結(jié)束觸摸
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 取消觸摸
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
二、代碼:
// 40日降水 折線圖(??) :高度height = 8 + 247 + 32
#import "GWHomeDays_TableFooterView.h"
@interface GWHomeDays_TableFooterView ()
@property (nonatomic, strong) UIImageView *backImg;
@property (nonatomic, strong) UIView *backView;
@property (nonatomic, strong) UILabel *titleL;
@property (nonatomic, strong) UIImageView *topSeparateImg;
/**
* 升溫 降溫 降水 次數(shù)
*/
@property (nonatomic, strong) UILabel *statisticsTipsL;
/**
* 1、lineBackRangeView 折線圖??:width:256, height:104,
*
* 2、lineLayerRangeView 折線范圍:從上面y=8的位置開始, width:256,height:78
* 40個(gè)塊,豎線在每一個(gè)塊的中間 width:256/40 = 6.4,下邊對應(yīng)雨圖??、雪圖??、灰色○(無降水)
* 3、fatherLayer 創(chuàng)建曲線圖的父layer:78-8 ,給小圓圈??預(yù)留位置,小圓圈 6x6
*/
@property (nonatomic, strong) UIView *lineBackRangeView; // 整個(gè)折線圖范圍view
@property (nonatomic, strong) UIView *lineLayerRangeView;// 劃線范圍范圍view(有數(shù)據(jù)之后,再創(chuàng)建)
@property (nonatomic, strong) CAShapeLayer *fatherLayer; // 折線圖的父layer (有數(shù)據(jù)之后,再創(chuàng)建)
@property (nonatomic, strong) CAShapeLayer *circleBackLayer; // 小圓點(diǎn)的背景l(fā)ayer,(手指touch移動(dòng)的時(shí)候,刪除 并重新繪制小圓點(diǎn))
@property (nonatomic, strong) NSArray *circleArray; // 小圓點(diǎn)的坐標(biāo)CGPoint數(shù)組
@property (nonatomic, strong) UIButton *weatherTipsBut; // 在觸摸曲線圖時(shí),顯示小圓點(diǎn)的同時(shí),顯示提示框,會隨著左右滑動(dòng)(改變偏移量)
// 折線圖其他標(biāo)簽??:(降水量、時(shí)間、降水類型圖標(biāo))
@property (nonatomic, strong) UILabel *highestTempL; // 最高溫
@property (nonatomic, strong) UILabel *lowestTempL; // 最低溫
@property (nonatomic, strong) UILabel *rainTitleL; // "降水"
@property (nonatomic, strong) UIView *rainBackImgView; // 下方的40個(gè)降水圖標(biāo) (有數(shù)據(jù)之后,再創(chuàng)建)
/** 最下邊的 時(shí)間 */
@property (nonatomic, strong) UILabel *rainTimeL1;
@property (nonatomic, strong) UILabel *rainTimeL2;
@property (nonatomic, strong) UILabel *rainTimeL3;
@property (nonatomic, strong) UILabel *rainTimeL4;
@property (nonatomic, strong) UILabel *rainTimeL5;
@end
@implementation GWHomeDays_TableFooterView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = UIColor.clearColor;
[self setupUI];
}
return self;
}
- (void)refreshTableFooterView {
// heat、cool、rain、snow、
if (self.fortyDaysModel.fortyStatistics.count >= 3) {
NSInteger heatCount = 0;
NSInteger coolCount = 0;
NSInteger rainCount = 0;
for (FortyStatisticsModel *statisticsModel in self.fortyDaysModel.fortyStatistics) {
if ([statisticsModel.type isEqualToString:@"heat"]) {
heatCount = statisticsModel.count;
}
if ([statisticsModel.type isEqualToString:@"cool"]) {
coolCount = statisticsModel.count;
}
if ([statisticsModel.type isEqualToString:@"rain"]) {
rainCount = statisticsModel.count;
}
}
self.statisticsTipsL.text = [NSString stringWithFormat:@"升溫%ld次 / 降溫%ld次 / 降水%ld次", heatCount, coolCount, rainCount];
}
if (self.statisticsTipsL.text.length > 0) {
NSMutableAttributedString *contentStr = [[NSMutableAttributedString alloc]initWithString:self.statisticsTipsL.text];
[contentStr addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:12]
range:[self.statisticsTipsL.text rangeOfString:self.statisticsTipsL.text]];
[contentStr addAttribute:NSForegroundColorAttributeName value:RGBA(238, 197, 116, 1) range:[self.statisticsTipsL.text rangeOfString:self.statisticsTipsL.text]];
for (int i = 0; i < self.statisticsTipsL.text.length; i++) {
NSRange range = {i, 1};// 范圍是起點(diǎn)和長度,而非起點(diǎn)和終點(diǎn)
NSString * subStr = [self.statisticsTipsL.text substringWithRange:range];
if ([subStr isStringContainNumberWith:subStr]) { // 判斷是否是數(shù)字,改變數(shù)字的大小和顏色
[contentStr addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*20 weight:UIFontWeightBold]
range:range];
[contentStr addAttribute:NSForegroundColorAttributeName value:RGBA(193, 162, 122, 1) range:range];
}
}
self.statisticsTipsL.attributedText = contentStr;
}
/**
* 折線圖??
*/
[self.lineLayerRangeView removeFromSuperview];
[self.fatherLayer removeFromSuperlayer];
[self.circleBackLayer removeFromSuperlayer];
[self.rainBackImgView removeFromSuperview];
[self.weatherTipsBut removeFromSuperview];
self.highestTempL.text = [NSString stringWithFormat:@"%ld°", self.fortyDaysModel.fortyTemp.highest.value];
self.lowestTempL.text = [NSString stringWithFormat:@"%ld°", self.fortyDaysModel.fortyTemp.lowest.value];
self.circleArray = [NSArray array];
if (self.fortyDaysModel.fortyDetail.count >= 40) { // 有數(shù)據(jù)時(shí)
self.rainTimeL1.text = self.fortyDaysModel.fortyDetail[0].date;
self.rainTimeL2.text = self.fortyDaysModel.fortyDetail[9].date;
self.rainTimeL3.text = self.fortyDaysModel.fortyDetail[19].date;
self.rainTimeL4.text = self.fortyDaysModel.fortyDetail[29].date;
self.rainTimeL5.text = self.fortyDaysModel.fortyDetail[39].date;
// 下邊的一整行 是否有降水圖標(biāo):
_rainBackImgView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*50, [UIScreen mainScreen].bounds.size.width/375*(99 + 104 + 2), [UIScreen mainScreen].bounds.size.width/375*256, [UIScreen mainScreen].bounds.size.width/375*10)];
_rainBackImgView.backgroundColor = RGBA(221, 255, 247, 1);
[self.backView addSubview:self.rainBackImgView];
for (int i = 0; i < self.fortyDaysModel.fortyDetail.count; i++) {
FortyDetailModel *detailModel = self.fortyDaysModel.fortyDetail[i];
/** 降水 */
UIImageView *rainImg = [[UIImageView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*(0.4 + 6.4*i), [UIScreen mainScreen].bounds.size.width/375*2, [UIScreen mainScreen].bounds.size.width/375*6, [UIScreen mainScreen].bounds.size.width/375*6)];
if (detailModel.precipitation == 1) {
rainImg.image = [UIImage imageNamed:@"club_weather_大雨點(diǎn)_icon"];
} else {
rainImg.image = [UIImage imageNamed:@"ic_weather_sunny_icon"];
}
// rainImg.tag = 100+i;
[self.rainBackImgView addSubview:rainImg];
/** 背景豎線 */
if ([self.lineBackRangeView viewWithTag:1000+i]) { // 如果,之前已經(jīng)創(chuàng)建,就是用之前的,沒有在創(chuàng)建
UIView *lineView = [self.lineBackRangeView viewWithTag:1000+i];
lineView.backgroundColor = RGBA(193, 162, 122, 0.1);
lineView.tag = 1000+i; // 手指觸摸之后,改區(qū)域范圍內(nèi)的豎線 “不半透明”,添加標(biāo)簽
} else {
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*((6.4-1)/2 + 6.4*i), 0, 1, [UIScreen mainScreen].bounds.size.width/375*104)];
lineView.backgroundColor = RGBA(193, 162, 122, 0.1);
lineView.tag = 1000+i; // 手指觸摸之后,改區(qū)域范圍內(nèi)的豎線 “不半透明”,添加標(biāo)簽
[self.lineBackRangeView addSubview:lineView];
}
/**
* 折線圖??:width:256, height:104,
*
* 折線范圍:從上面y=8的位置開始, width:256,height:78
* 40個(gè)塊,豎線在每一個(gè)塊的中間 width:256/40 = 6.4,下邊對應(yīng)雨圖??、雪圖??、灰色○(無降水)
*/
_lineLayerRangeView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.width/375*8, [UIScreen mainScreen].bounds.size.width/375*256, [UIScreen mainScreen].bounds.size.width/375*78)];
_lineLayerRangeView.backgroundColor = RGBA(214, 249, 255, 0.5);
[self.lineBackRangeView addSubview:self.lineLayerRangeView];
/** 1、創(chuàng)建曲線圖的父layer:78-7 ,給小圓圈??預(yù)留位置 */
_fatherLayer = [[CAShapeLayer alloc] init];
_fatherLayer.strokeColor = [UIColor clearColor].CGColor;
UIBezierPath *bezierPath = [UIBezierPath
bezierPathWithRoundedRect:CGRectMake(0, 0, self.lineLayerRangeView.frame.size.width, [UIScreen mainScreen].bounds.size.width/375*(78))
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake([UIScreen mainScreen].bounds.size.width/375*0, [UIScreen mainScreen].bounds.size.width/375*0)];
_fatherLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*0.01;
// 顏色
_fatherLayer.strokeColor = [UIColor clearColor].CGColor;
// 背景填充色
// _fatherLayer.fillColor = [UIColor clearColor].CGColor;
_fatherLayer.fillColor = RGBA(233, 255, 244, 0.5).CGColor;
_fatherLayer.path = [bezierPath CGPath];
[self.lineLayerRangeView.layer addSublayer:self.fatherLayer];
/** 小圓點(diǎn)??的父layer */
_circleBackLayer = [[CAShapeLayer alloc] init];
_circleBackLayer.strokeColor = [UIColor clearColor].CGColor;
UIBezierPath *circleBezierPath = [UIBezierPath
bezierPathWithRoundedRect:CGRectMake(0, 0, self.lineLayerRangeView.frame.size.width, [UIScreen mainScreen].bounds.size.width/375*(78))
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake([UIScreen mainScreen].bounds.size.width/375*0, [UIScreen mainScreen].bounds.size.width/375*0)];
_circleBackLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*0.01;
// 顏色
_circleBackLayer.strokeColor = [UIColor clearColor].CGColor;
// 背景填充色
_circleBackLayer.fillColor = [UIColor clearColor].CGColor;
_circleBackLayer.path = [circleBezierPath CGPath];
[self.lineLayerRangeView.layer addSublayer:self.circleBackLayer];
/// 先找到40天的 最大溫度和最低溫度:(獲取曲線圖??的范圍)
NSInteger maxTemp = 0;
NSInteger minTemp = 0;
for (int i = 0; i < self.fortyDaysModel.fortyDetail.count; i++) {
FortyDetailModel *detailModel = self.fortyDaysModel.fortyDetail[i];
NSInteger i_temp = detailModel.dayTemp;
// NSLog(@"一天的溫度???? %.2f ????", i_temp);
if (i == 0) {
maxTemp = i_temp;
minTemp = i_temp;
}
if (maxTemp > i_temp) {
maxTemp = maxTemp;
} else {
maxTemp = i_temp;
}
if (minTemp > i_temp) {
minTemp = i_temp;
} else {
minTemp = minTemp;
}
}
// 溫度之差 的 溫度范圍:溫度三種情況都是這個(gè)減法獲取溫度的范圍
NSInteger maxTempRange = maxTemp - minTemp;
double maxTempRange_value = 0;
if (maxTempRange == 0) {
maxTempRange_value = 0;
} else {
maxTempRange_value = 70 / maxTempRange;
}
// 小圓點(diǎn)的中心點(diǎn)坐標(biāo) point數(shù)組:
NSMutableArray *circleArray = [NSMutableArray arrayWithCapacity:0];
/** 溫度 path */
UIBezierPath *temp_Path = [UIBezierPath bezierPath];
// 設(shè)置path的 起始點(diǎn) 和 其他點(diǎn)
for (int k = 0; k < self.fortyDaysModel.fortyDetail.count; k++) {
FortyDetailModel *detailModel = self.fortyDaysModel.fortyDetail[k];
NSInteger nextTemp = detailModel.dayTemp;
// 兩個(gè)相鄰 端點(diǎn) 的位置間隔:67
if (k == 0) { // 第一個(gè),特殊處理
// 第一個(gè)點(diǎn),起始點(diǎn)。
[temp_Path moveToPoint:CGPointMake([UIScreen mainScreen].bounds.size.width/375*6.4/2, [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * (nextTemp - minTemp)))];
// 端點(diǎn)位置CGPoint
CGPoint circlePoint = CGPointMake([UIScreen mainScreen].bounds.size.width/375*(6.4/2), [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * (nextTemp - minTemp)));
NSValue* circleValue = [NSValue valueWithCGPoint:circlePoint];
[circleArray addObject:circleValue];
} else {
FortyDetailModel *detailModel0 = self.fortyDaysModel.fortyDetail[k-1];
NSInteger lastTemp = detailModel0.dayTemp;
// 原理(這里的天氣溫度曲線):endPoint:下一個(gè)端點(diǎn)的x、y軸坐標(biāo), controlPoint1:X軸坐標(biāo)是上一個(gè)startPoint.x和下一個(gè)endPoint.x的中間X坐標(biāo)位置,Y軸是和上一個(gè)startPoint.y, controlPoint2:X軸坐標(biāo)是上一個(gè)startPoint.x和下一個(gè)endPoint.x的中間X坐標(biāo)位置,Y軸是和下一個(gè)endPoint.y,
[temp_Path addCurveToPoint:CGPointMake([UIScreen mainScreen].bounds.size.width/375*(6.4/2 + 6.4*k) , [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * (nextTemp - minTemp)))
controlPoint1:CGPointMake([UIScreen mainScreen].bounds.size.width/375*(6.4/2 + 6.4*k - 6.4/2), [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * (lastTemp - minTemp)))
controlPoint2:CGPointMake([UIScreen mainScreen].bounds.size.width/375*(6.4/2 + 6.4*k - 6.4/2), [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * ((nextTemp - minTemp))))];
// 端點(diǎn)位置CGPoint
CGPoint circlePoint = CGPointMake([UIScreen mainScreen].bounds.size.width/375*(6.4/2+ (6.4*k)), [UIScreen mainScreen].bounds.size.width/375*(74 - maxTempRange_value * (nextTemp - minTemp)));
NSValue* circleValue = [NSValue valueWithCGPoint:circlePoint];
[circleArray addObject:circleValue];
}
}
CAShapeLayer *temp_Layer = [[CAShapeLayer alloc] init];
// 線寬
temp_Layer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*2;
// 線條的顏色
temp_Layer.strokeColor = RGBA(193, 162, 122, 1).CGColor;
// 背景填充色
temp_Layer.fillColor = [UIColor clearColor].CGColor;
// 將UIBezierPath類轉(zhuǎn)換成CGPath,類似于UIColor的CGColor
temp_Layer.path = [temp_Path CGPath];
[self.fatherLayer addSublayer:temp_Layer];
/** 所有的曲線端點(diǎn)(小圓點(diǎn))的位置:CGPoint */
self.circleArray = [circleArray copy];
/** 折線圖??中的小圓點(diǎn) */
// for (NSValue *circleValue in circleArray) {
// /** 折線圖??中的小圓點(diǎn) */
// CGPoint circlePoint = [circleValue CGPointValue];
//
// CAShapeLayer *circleLayer = [CAShapeLayer layer];
// // 線寬
// circleLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*1; // 10 - 6 = 4
// circleLayer.lineCap = kCALineCapRound; // 端點(diǎn)樣式
// circleLayer.lineJoin = kCALineJoinMiter; // 終點(diǎn)處理
// // 線條的顏色
// circleLayer.strokeColor = RGBA(193, 162, 122, 1).CGColor;
// // 背景填充色
// circleLayer.fillColor = [UIColor whiteColor].CGColor;
// // 設(shè)置線寬、線間距(虛線)
// // [circleLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:2], [NSNumber numberWithInt:2], nil]];
//
// // 設(shè)置半徑
// CGFloat circleRadius = [UIScreen mainScreen].bounds.size.width/375*3;
// // bezierPathWithArcCenter 中心點(diǎn),下面就讓addSublayer了,那么就設(shè)置self.bezierBackImg.layer的 中心點(diǎn)就好了,寬/2,高/2
// UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:circlePoint radius:circleRadius startAngle:(0*M_PI) endAngle:(2*M_PI) clockwise:YES]; // 終止點(diǎn)(60%幾率時(shí)):(2*0.6 - 0.25)*M_PI,clockwise 順時(shí)針 YES, 逆時(shí)針 NO
// circleLayer.path = [circlePath CGPath];
// [self.circleBackLayer addSublayer:circleLayer];
// }
// @property (nonatomic, strong) UIView *lineBackRangeView; // 整個(gè)折線圖范圍view
// @property (nonatomic, strong) UIView *lineLayerRangeView;// 劃線范圍范圍view(有數(shù)據(jù)之后,再創(chuàng)建)
// @property (nonatomic, strong) CAShapeLayer *fatherLayer; // 折線圖的父layer (有數(shù)據(jù)之后,再創(chuàng)建)
// UIView *lineView0 = [self.lineBackRangeView viewWithTag:1020];
// lineView0.backgroundColor = RGBA(193, 162, 122, 1);
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
// 手指觸摸 開始
UITouch *touch = touches.anyObject;
CGPoint point = [touch locationInView:self.lineLayerRangeView];
NSLog(@"?????? 開始觸摸屏幕 手指所在 折線圖??上的位置 point.X ==== %f,\n point.Y ==== %f", point.x, point.y);
// 條件:有數(shù)據(jù),并且 點(diǎn)擊的是這個(gè)曲線的范圍UIview內(nèi):
if (self.fortyDaysModel.fortyDetail.count >= 40 && CGRectContainsPoint(self.lineLayerRangeView.frame, point)) { // 有數(shù)據(jù)時(shí)
// (1) 豎線:
for (int i = 0; i < self.fortyDaysModel.fortyDetail.count; i++) {
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
UIView *lineView = [self.lineBackRangeView viewWithTag:1000+i]; // 找到加tag的那一個(gè),該變其顏色
if (indexItem < self.circleArray.count && indexItem >= 0) {
lineView.backgroundColor = RGBA(193, 162, 122, 0.2);
}
if (i == indexItem) { // 手指在到第幾個(gè)
lineView.backgroundColor = RGBA(193, 162, 122, 1);
}
}
// (2) 小圓點(diǎn):
if (self.circleArray.count > 0) {
/** 折線圖??中的小圓點(diǎn) */
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
if (indexItem < self.circleArray.count && indexItem >= 0) {
[self.circleBackLayer removeAllSublayers];// 刪除所有子layer,重新繪制子layer
NSValue *circleValue = self.circleArray[indexItem];
CGPoint circlePoint = [circleValue CGPointValue];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
// 線寬
circleLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*1; // 10 - 6 = 4
circleLayer.lineCap = kCALineCapRound; // 端點(diǎn)樣式
circleLayer.lineJoin = kCALineJoinMiter; // 終點(diǎn)處理
// 線條的顏色
circleLayer.strokeColor = RGBA(193, 162, 122, 1).CGColor;
// 背景填充色
circleLayer.fillColor = [UIColor whiteColor].CGColor;
// 設(shè)置線寬、線間距(虛線)
// [circleLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:2], [NSNumber numberWithInt:2], nil]];
// 設(shè)置半徑
CGFloat circleRadius = [UIScreen mainScreen].bounds.size.width/375*3;
// bezierPathWithArcCenter 中心點(diǎn),下面就讓addSublayer了,那么就設(shè)置self.bezierBackImg.layer的 中心點(diǎn)就好了,寬/2,高/2
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:circlePoint radius:circleRadius startAngle:(0*M_PI) endAngle:(2*M_PI) clockwise:YES]; // 終止點(diǎn)(60%幾率時(shí)):(2*0.6 - 0.25)*M_PI,clockwise 順時(shí)針 YES, 逆時(shí)針 NO
circleLayer.path = [circlePath CGPath];
[self.circleBackLayer addSublayer:circleLayer];
}
}
// (3) 提示框:可移動(dòng) 256 - 130 = 126 的距離,
// 計(jì)算到達(dá) 第幾個(gè)四塊內(nèi)
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
if (indexItem < self.circleArray.count && indexItem >= 0) { // 防止數(shù)組越界
[self.weatherTipsBut removeFromSuperview];
FortyDetailModel *detailModel = self.fortyDaysModel.fortyDetail[indexItem];
_weatherTipsBut = [[UIButton alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*50, [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23)];
[_weatherTipsBut setBackgroundImage:[UIImage imageNamed:@"addCity_bg_icon"] forState:UIControlStateNormal];
[_weatherTipsBut setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
_weatherTipsBut.titleLabel.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*12 weight:UIFontWeightRegular];
_weatherTipsBut.titleLabel.adjustsFontSizeToFitWidth = YES;
_weatherTipsBut.titleLabel.minimumScaleFactor = 0.3;
[self.backView addSubview:self.weatherTipsBut];
[self.weatherTipsBut setTitle:[NSString stringWithFormat:@"%@°", detailModel.detail] forState:UIControlStateNormal];
// 重新設(shè)置X軸的坐標(biāo)偏移量:
if ((50 + indexItem*6.4) < (50 + 130/2)) { // 貼著 最左邊
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
} else if ((50 + indexItem*6.4) > (50 + 256 - 130/2)) { // 貼著 最右邊
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50 + 256 - 130), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
} else { // (50 + indexItem*6.4) >= (50 + 130/2) && (50 + indexItem*6.4) <= (50 + 256 - 130/2)
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50 + indexItem*6.4 - 130/2), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
}
}
}
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
// 手指觸摸 移動(dòng)
// iOS 怎么樣獲取手指在view上滑動(dòng)的起點(diǎn)坐標(biāo)與終點(diǎn)坐標(biāo)
UITouch *touch = touches.anyObject;
CGPoint point = [touch locationInView:self.lineLayerRangeView];
// NSLog(@"???? 手指所在 折線圖??上的位置 point.X ==== %f,\n point.Y ==== %f", point.x, point.y);
/**
* 當(dāng)?shù)讓右晥D是個(gè) UITableView,在觸摸折線圖??,并在其??上面左右滑動(dòng)時(shí),暫時(shí)禁止tableview的滑動(dòng)效果,
*
* 再,觸摸結(jié)束或point.y > point.x時(shí),回復(fù)tableview的滑動(dòng)
*
*/
if ([self.superview isKindOfClass:[UITableView class]]) {
UITableView *tableView = (UITableView *)self.superview;
if (point.x > point.y) {
tableView.scrollEnabled = NO;
} else {
tableView.scrollEnabled = YES;
}
}
// 條件:有數(shù)據(jù),并且 點(diǎn)擊的是這個(gè)曲線的范圍UIview內(nèi):
if (self.fortyDaysModel.fortyDetail.count >= 40 && CGRectContainsPoint(self.lineLayerRangeView.frame, point)) { // 有數(shù)據(jù)時(shí)
// (1) 豎線:
for (int i = 0; i < self.fortyDaysModel.fortyDetail.count; i++) {
// 計(jì)算到達(dá) 第幾個(gè)四塊內(nèi)
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
UIView *lineView = [self.lineBackRangeView viewWithTag:1000+i]; // 找到加tag的那一個(gè),該變其顏色
if (indexItem < self.circleArray.count && indexItem >= 0) {
lineView.backgroundColor = RGBA(193, 162, 122, 0.2);
}
if (i == indexItem) { // 手指在到第幾個(gè)
lineView.backgroundColor = RGBA(193, 162, 122, 1);
}
}
// (2) 小圓點(diǎn):
if (self.circleArray.count > 0) {
/** 折線圖??中的小圓點(diǎn) */
// 計(jì)算到達(dá) 第幾個(gè)四塊內(nèi)
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
if (indexItem < self.circleArray.count && indexItem >= 0) {
[self.circleBackLayer removeAllSublayers];// 刪除所有子layer,重新繪制子layer
NSValue *circleValue = self.circleArray[indexItem];
CGPoint circlePoint = [circleValue CGPointValue];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
// 線寬
circleLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*1; // 10 - 6 = 4
circleLayer.lineCap = kCALineCapRound; // 端點(diǎn)樣式
circleLayer.lineJoin = kCALineJoinMiter; // 終點(diǎn)處理
// 線條的顏色
circleLayer.strokeColor = RGBA(193, 162, 122, 1).CGColor;
// 背景填充色
circleLayer.fillColor = [UIColor whiteColor].CGColor;
// 設(shè)置線寬、線間距(虛線)
// [circleLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:2], [NSNumber numberWithInt:2], nil]];
// 設(shè)置半徑
CGFloat circleRadius = [UIScreen mainScreen].bounds.size.width/375*3;
// bezierPathWithArcCenter 中心點(diǎn),下面就讓addSublayer了,那么就設(shè)置self.bezierBackImg.layer的 中心點(diǎn)就好了,寬/2,高/2
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:circlePoint radius:circleRadius startAngle:(0*M_PI) endAngle:(2*M_PI) clockwise:YES]; // 終止點(diǎn)(60%幾率時(shí)):(2*0.6 - 0.25)*M_PI,clockwise 順時(shí)針 YES, 逆時(shí)針 NO
circleLayer.path = [circlePath CGPath];
[self.circleBackLayer addSublayer:circleLayer];
}
}
// (3) 提示框:可移動(dòng) 256 - 130 = 126 的距離,
// 計(jì)算到達(dá) 第幾個(gè)四塊內(nèi)
CGFloat touch_Point_X = point.x;
NSInteger indexItem = touch_Point_X / ([UIScreen mainScreen].bounds.size.width/375*6.4);
if (indexItem < self.circleArray.count && indexItem >= 0) { // 防止數(shù)組越界
[self.weatherTipsBut removeFromSuperview];
FortyDetailModel *detailModel = self.fortyDaysModel.fortyDetail[indexItem];
_weatherTipsBut = [[UIButton alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*50, [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23)];
[_weatherTipsBut setBackgroundImage:[UIImage imageNamed:@"addCity_bg_icon"] forState:UIControlStateNormal];
[_weatherTipsBut setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
_weatherTipsBut.titleLabel.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*12 weight:UIFontWeightRegular];
_weatherTipsBut.titleLabel.adjustsFontSizeToFitWidth = YES;
_weatherTipsBut.titleLabel.minimumScaleFactor = 0.3;
[self.backView addSubview:self.weatherTipsBut];
[self.weatherTipsBut setTitle:[NSString stringWithFormat:@"%@°", detailModel.detail] forState:UIControlStateNormal];
// 重新設(shè)置X軸的坐標(biāo)偏移量:
if ((50 + indexItem*6.4) < (50 + 130/2)) { // 貼著 最左邊
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
} else if ((50 + indexItem*6.4) > (50 + 256 - 130/2)) { // 貼著 最右邊
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50 + 256 - 130), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
} else { // (50 + indexItem*6.4) >= (50 + 130/2) && (50 + indexItem*6.4) <= (50 + 256 - 130/2)
self.weatherTipsBut.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*(50 + indexItem*6.4 - 130/2), [UIScreen mainScreen].bounds.size.width/375*(83), [UIScreen mainScreen].bounds.size.width/375*130, [UIScreen mainScreen].bounds.size.width/375*23);
}
}
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
// 手指觸摸 結(jié)束
NSLog(@"???????? 手指觸摸 結(jié)束");
/**
* 當(dāng)?shù)讓右晥D是個(gè) UITableView,在觸摸折線圖??,并在其??上面左右滑動(dòng)時(shí),暫時(shí)禁止tableview的滑動(dòng)效果,
*
* 再,觸摸結(jié)束或point.y > point.x時(shí),回復(fù)tableview的滑動(dòng)
*
*/
if ([self.superview isKindOfClass:[UITableView class]]) {
UITableView *tableView = (UITableView *)self.superview;
tableView.scrollEnabled = YES;
}
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
// 取消觸摸時(shí)
NSLog(@"???? 取消觸摸 ????????");
}
UI添加到該self.View 上:
- (void)setupUI {
_backImg = [[UIImageView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*24, [UIScreen mainScreen].bounds.size.width/375*8, [UIScreen mainScreen].bounds.size.width/375*(375 - 24*2), [UIScreen mainScreen].bounds.size.width/375*247)];
_backImg.image = [UIImage imageNamed:@"cityList_bg_icon"];
[self addSubview:self.backImg];
_backView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*24, [UIScreen mainScreen].bounds.size.width/375*8, [UIScreen mainScreen].bounds.size.width/375*(375 - 24*2), [UIScreen mainScreen].bounds.size.width/375*247)];
_backView.backgroundColor = UIColor.clearColor;
[self addSubview:self.backView];
_titleL = [[UILabel alloc] init];
_titleL.text = @"40日趨勢";
_titleL.textColor = RGBA(9, 9, 9, 1);
_titleL.textAlignment = NSTextAlignmentLeft;
_titleL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*14 weight:UIFontWeightMedium];
[self.backView addSubview:self.titleL];
[self.titleL makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.backView.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*18);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*18);
}];
_topSeparateImg = [[UIImageView alloc] init];
_topSeparateImg.backgroundColor = RGBA(193, 162, 122, 0.7);
[self.backView addSubview:self.topSeparateImg];
[self.topSeparateImg makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.titleL.mas_bottom).offset([UIScreen mainScreen].bounds.size.width/375*3);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*15);
make.right.mas_equalTo(self.backView.mas_right).offset(-[UIScreen mainScreen].bounds.size.width/375*15);
make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*14);
}];
_statisticsTipsL = [[UILabel alloc] init];
_statisticsTipsL.textColor = RGBA(9, 9, 9, 0.7);
_statisticsTipsL.textAlignment = NSTextAlignmentCenter;
_statisticsTipsL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*12 weight:UIFontWeightRegular];
[self.backView addSubview:self.statisticsTipsL];
[self.statisticsTipsL makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.backView.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*(65+14));
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*18);
make.right.mas_equalTo(self.backView.mas_right).offset(-[UIScreen mainScreen].bounds.size.width/375*18);
}];
/**
* 折線圖??:width:256, height:104,
*
* 折線范圍:從上面y=8的位置開始, width:256,height:78
* 40個(gè)塊,豎線在每一個(gè)塊的中間,下邊對應(yīng)雨圖??、雪圖??、灰色○(無降水)
*/
_lineBackRangeView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*50, [UIScreen mainScreen].bounds.size.width/375*99, [UIScreen mainScreen].bounds.size.width/375*256, [UIScreen mainScreen].bounds.size.width/375*104)];
self.lineBackRangeView.backgroundColor = RGBA(232, 226, 255, 1);
[self.backView addSubview:self.lineBackRangeView];
// 折線圖其他標(biāo)簽??:(降水量、時(shí)間、降水類型圖標(biāo))
// 最高溫
_highestTempL = [[UILabel alloc] init];
_highestTempL.text = @"°";
_highestTempL.textColor = RGBA(0, 0, 0, 0.5);
_highestTempL.textAlignment = NSTextAlignmentLeft;
_highestTempL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*12 weight:UIFontWeightRegular];
[self.backView addSubview:self.highestTempL];
[self.highestTempL makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.lineBackRangeView.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*8);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*18);
}];
// 最低溫
_lowestTempL = [[UILabel alloc] init];
_lowestTempL.text = @"°";
_lowestTempL.textColor = RGBA(0, 0, 0, 0.5);
_lowestTempL.textAlignment = NSTextAlignmentLeft;
_lowestTempL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*12 weight:UIFontWeightRegular];
[self.backView addSubview:self.lowestTempL];
[self.lowestTempL makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.lineBackRangeView.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*(8+78));
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*18);
}];
_rainTitleL = [[UILabel alloc] init];
_rainTitleL.text = @"降水";
_rainTitleL.textColor = RGBA(0, 0, 0, 0.5);
_rainTitleL.textAlignment = NSTextAlignmentLeft;
_rainTitleL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTitleL];
[self.rainTitleL makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.lineBackRangeView.mas_bottom).offset([UIScreen mainScreen].bounds.size.width/375*2);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*18);
}];
/** 最下邊的 時(shí)間 */
_rainTimeL1 = [[UILabel alloc] init];
_rainTimeL1.textColor = RGBA(0, 0, 0, 0.5);
_rainTimeL1.textAlignment = NSTextAlignmentLeft;
_rainTimeL1.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTimeL1];
[self.rainTimeL1 makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.rainTitleL.mas_bottom).offset([UIScreen mainScreen].bounds.size.width/375*3);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*50);
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*30);
}];
_rainTimeL2 = [[UILabel alloc] init];
_rainTimeL2.textColor = RGBA(0, 0, 0, 0.5);
_rainTimeL2.textAlignment = NSTextAlignmentCenter;
_rainTimeL2.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTimeL2];
[self.rainTimeL2 makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.rainTimeL1);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*(50 +30 +26.5));
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*30);
}];
_rainTimeL3 = [[UILabel alloc] init];
_rainTimeL3.textColor = RGBA(0, 0, 0, 0.5);
_rainTimeL3.textAlignment = NSTextAlignmentCenter;
_rainTimeL3.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTimeL3];
[self.rainTimeL3 makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.rainTimeL1);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*(50 +30*2 +26.5*2));
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*30);
}];
_rainTimeL4 = [[UILabel alloc] init];
_rainTimeL4.textColor = RGBA(0, 0, 0, 0.5);
_rainTimeL4.textAlignment = NSTextAlignmentCenter;
_rainTimeL4.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTimeL4];
[self.rainTimeL4 makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.rainTimeL1);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*(50 +30*3 +26.5*3));
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*30);
}];
_rainTimeL5 = [[UILabel alloc] init];
_rainTimeL5.textColor = RGBA(0, 0, 0, 0.5);
_rainTimeL5.textAlignment = NSTextAlignmentRight;
_rainTimeL5.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*10 weight:UIFontWeightRegular];
[self.backView addSubview:self.rainTimeL5];
[self.rainTimeL5 makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.rainTimeL1);
make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*(50 +30*4 +26.5*4));
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*30);
}];
}
