一、封装了一个简便好用的天气框控件,有几个特点:
1、轻量级,使用百度天气接口,显示某个城市当前的天气,配有天气图标,日期。
2、使用封装的初始化方法,实例化控件,天气框的大小是固定的,字体颜色可以改变。
3、需要AFNetworking、SDWebImage框架(一般的项目中都会使用)、使用了一个关于UIView的frame扩展(方便控件的布局,已在下文贴出源码)。
4、点击天气框任意位置自动移除。
5、效果图示:
二、原代码:
1、.h中的声明
@interface ZQWeatherView : UIView /** * 需要AFNetworking、SDWebImage框架 ; 加载的是当天的天气 ; 宽110,高73 ; 点击天气框移除 * * @param frame 天气框架的frame,宽高无效 * @param city 城市 * @param color 文字的颜色 * * @return 返回天气框 */ -(instancetype)initWithFrame:(CGRect)frame City:(NSString*)city WritingColor :(UIColor *)color; @end
2、网络请求的一些参数,定义了两个宏,使用方便
//定义百度天气的KEY #define kBDWeather_KEY @"17IvzuqmKrK1cGwNL6VQebF9" //定义百度天气的接口URL #define kGetWeather_URL(city) ([NSString stringWithFormat: @"http://api.map.baidu.com/telematics/v3/weather?location=%@&output=json&ak=%@", city, kBDWeather_KEY])
3、.m中的全局私有属性
@interface ZQWeatherView () @property (nonatomic,strong) UIImageView * img; @property (nonatomic,strong) UILabel * lab; @property (nonatomic,strong) UILabel * dateLabel; @property (nonatomic,strong) UILabel * city; @property (nonatomic,strong)UIButton * cancleBtn; @property(nonatomic,strong) UIView * back; @property (nonatomic,strong) NSDictionary * weatherDataDict; @property (nonatomic,strong) UIActivityIndicatorView * acView; @end
4、.m文件中其他内容
1 //提供对象方法初始化控件 2 3 -(instancetype)initWithFrame:(CGRect)frame City:(NSString*)city WritingColor :(UIColor *)color 4 { 5 6 self = [super init]; 7 8 if (self) { 9 10 //传入的宽高无效 11 self.frame = CGRectMake(frame.origin.x, frame.origin.y, 110, 73); 12 self.backgroundColor = [UIColor clearColor]; 13 self.layer.cornerRadius = 5; 14 self.layer.masksToBounds = YES; 15 16 //生成背后的蒙版 17 self.back = [[UIView alloc]init]; 18 self.back.backgroundColor=[UIColor blackColor]; 19 self.back.alpha=0.3; 20 [self addSubview:self.back]; 21 22 23 //天气图标 24 self.img = [[UIImageView alloc]init]; 25 self.img.layer.cornerRadius=3; 26 self.img.layer.masksToBounds=YES; 27 [self addSubview:self.img]; 28 29 //天气信息 30 self.lab = [[UILabel alloc]init]; 31 self.lab.font=[UIFont systemFontOfSize:14]; 32 [self addSubview:self.lab]; 33 34 //添加城市信息 35 self.city = [[UILabel alloc]init]; 36 [self.city sizeToFit]; 37 self.city.font=[UIFont systemFontOfSize:18]; 38 [self addSubview:self.city]; 39 self.city.textAlignment = NSTextAlignmentCenter; 40 41 //日期栏 42 self.dateLabel= [[UILabel alloc]init]; 43 self.dateLabel.font = [UIFont systemFontOfSize:11]; 44 [self addSubview:self.dateLabel]; 45 46 47 48 //添加一个按钮,移除天气框(按钮大小和天气框一样) 49 self.cancleBtn = [[UIButton alloc]init]; 50 [self.cancleBtn setBackgroundColor:[UIColor clearColor]]; 51 [self.cancleBtn addTarget:self action:@selector(cancleClick:) forControlEvents:UIControlEventTouchUpInside]; 52 [self addSubview:self.cancleBtn]; 53 54 55 dispatch_async(dispatch_get_main_queue(), ^{ 56 57 [self.acView startAnimating]; 58 59 //加载天气数据 (百度天气) 60 61 [self loadWeatherData:city]; 62 63 }); 64 65 //设置几个控件的文字颜色 66 self.lab.textColor = color; 67 self.dateLabel.textColor= color; 68 self.city.textColor = color; 69 } 70 return self; 71 } 72 73 74 75 //加载数据 76 - (void)loadWeatherData:(NSString *)city { 77 78 NSString *urlString = kGetWeather_URL(city); 79 80 // 百分号转义 81 urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 82 83 //通过AFN 创建网络管理,发送网络请求 84 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 85 86 [manager GET:urlString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { 87 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 88 89 90 NSDictionary *dict = (NSDictionary *)responseObject; 91 92 //有数据时再往下进行 93 if (dict[@"results"]) { 94 95 [self.acView stopAnimating]; 96 97 98 self.weatherDataDict = dict; 99 100 //获取数据了,直接给控件赋值 101 102 // 1 图片 103 NSDictionary *dateDict = dict[@"results"][0][@"weather_data"][0]; 104 105 NSString *urlString = dateDict[@"dayPictureUrl"]; 106 107 NSURL *url = [NSURL URLWithString:urlString]; 108 109 [self.img sd_setImageWithURL:url]; 110 111 [self.img sizeToFit]; 112 113 //2 温度 114 NSString *temper = dateDict[@"date"]; 115 116 //字符串转为数组 117 NSArray *arr = [temper componentsSeparatedByString:@" "]; 118 119 NSString *arrthree = arr[2]; 120 121 NSString *temperlab1 = [arrthree substringFromIndex:4]; 122 123 NSString *temperlab =[temperlab1 substringToIndex:(temperlab1.length -1)]; 124 125 self.lab.text = [NSString stringWithFormat:@"今日温度:%@",temperlab]; 126 127 [self.lab sizeToFit]; 128 129 //3 日期 130 self.dateLabel.text = dict[@"date"]; 131 132 [self.dateLabel sizeToFit]; 133 134 //4 城市 135 self.city.text = city; 136 137 138 } 139 140 141 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 142 143 NSLog(@"网络错误"); 144 }]; 145 146 147 148 } 149 150 //布局所有子控件 151 -(void)layoutSubviews { 152 153 [super layoutSubviews]; 154 155 //布局 156 157 self.lab.frame = CGRectMake(10,8, self.lab.width, self.lab.height); 158 159 self.city.frame = CGRectMake(10, self.lab.bottom+2, self.width-35, 25); 160 161 self.img.frame = CGRectMake(self.width-10-20,self.lab.bottom+5,24,24); 162 163 self.dateLabel.frame = CGRectMake(10,self.city.bottom+3,self.dateLabel.width, self.dateLabel.height); 164 self.cancleBtn.frame=CGRectMake(0, 0, self.width, self.height); 165 self.back.frame=CGRectMake(0, 0, self.width, self.height); 166 167 self.acView.center = CGPointMake(self.width/2, self.height/2); 168 169 170 } 171 172 173 174 //移除天气框的方法 175 -(void)cancleClick:(UIButton *)btn 176 { 177 [self removeFromSuperview]; 178 } 179 180 //懒加载储存天气信息的字典 181 - (NSDictionary *)weatherDataDict { 182 183 if (!_weatherDataDict) { 184 185 _weatherDataDict = [[NSDictionary alloc]init]; 186 } 187 return _weatherDataDict; 188 } 189 190 //菊花转轮 191 -(UIActivityIndicatorView *)acView 192 { 193 if (!_acView) { 194 _acView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 195 196 [self addSubview:_acView]; 197 } 198 199 return _acView; 200 201 } 202
5、关于类扩展UIView+EXTFrame.h
@interface UIView (EXTFrame) @property (nonatomic,assign) CGFloat x; @property (nonatomic,assign) CGFloat y; @property (nonatomic,assign) CGFloat width; @property (nonatomic,assign) CGFloat height; @property (nonatomic, assign) CGPoint origin; @property (nonatomic, assign) CGFloat left; @property (nonatomic, assign) CGFloat right; @property (nonatomic, assign) CGFloat top; @property (nonatomic, assign) CGFloat bottom; @end
6、关于类扩展UIView+EXTFrame.m
@implementation UIView (EXTFrame) -(void)setX:(CGFloat)x { CGRect rect = self.frame; rect.origin.x=x; self.frame = rect; } -(CGFloat)x { return self.frame.origin.x; } -(void)setY:(CGFloat)y { CGRect rect = self.frame; rect.origin.y=y; self.frame=rect; } -(CGFloat)y { return self.frame.origin.y; } -(void)setWidth:(CGFloat)width { CGRect rect = self.frame; rect.size.width=width; self.frame=rect; } -(CGFloat)width { return self.frame.size.width; } -(void)setHeight:(CGFloat)height { CGRect rect = self.frame; rect.size.height=height; self.frame=rect; } -(CGFloat)height { return self.frame.size.height; } - (CGPoint)origin { return self.frame.origin; } - (void)setOrigin:(CGPoint)origin { CGRect frame = self.frame; frame.origin = origin; self.frame = frame; } - (void)setLeft:(CGFloat)left { self.origin = CGPointMake(left, self.origin.y); } - (CGFloat)left { return self.origin.x; } - (void)setRight:(CGFloat)right { self.origin = CGPointMake(right - self.width, self.origin.y); } - (CGFloat)right { return self.origin.x + self.width; } - (void)setTop:(CGFloat)top { self.origin = CGPointMake(self.origin.x, top); } - (CGFloat)top { return self.origin.y; } - (void)setBottom:(CGFloat)bottom { self.origin = CGPointMake(self.origin.x, bottom - self.height); } - (CGFloat)bottom { return self.origin.y + self.height; } @end
三、备注
最后添加的两个扩展是对UIView的frame 的扩展,可以很方便的设置控件的frame。
时间: 2024-10-11 08:08:10