-(void)viewDidLoad {
[super viewDidLoad];
WGHeaderView *headerView = [[WGHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 110)];
headerView.delegate_ = self;
[self.view addSubview: headerView];
self.headerView = headerView;
}
// 设置界面的高度
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);
}
更新widget视图:(demo目前只是按钮 不需要更新)
-(void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
// NCUpdateResultNewData 新的内容需要重新绘制视图
// NCUpdateResultNoData 部件不需要更新
// NCUpdateResultFailed 更新过程中发生错误
completionHandler(NCUpdateResultNoData);
}
运行程序:
因此还需要实现:
-(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets{
return UIEdgeInsetsMake(0, 10, 0, 10);
}
注意:该方法在iOS 10之后就被淘汰了!
实现点击按钮跳转:
配置URL schemes:
在按钮点击的方法里实现:(此处小编用的代理)
NSString *urlStr = [NSString stringWithFormat:@"medicalWdget://%li",index];
NSURL *url = [NSURL URLWithString:urlStr];
[self.extensionContext openURL:url completionHandler:^(BOOL success) {
}];
目前就可以跳转到app了!当然是四个按钮,你需要再AppDelegate里面进行处理:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
if ([url.scheme isEqualToString:@"medicalWdget"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"ExtenicationNotification" object:url.host];
}
return YES;
}
// ios9 之后
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
if ([url.scheme isEqualToString:@"medicalWdget"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"ExtenicationNotification" object:url.host];
}
![72BBF230-83EB-4650-BE27-EE0FBBAAD35F.png](http://img2.jintiankansha.me/get6?src=http://upload-images.jianshu.io/upload_images/1109379-2530dc667076faee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
return YES;
}
然后处理相应的通知,判断url.host点击的第几个按钮!
适配iOS 10:
NCWidgetDisplayMode
NCWidgetDisplayModeCompact, // Fixed height
NCWidgetDisplayModeExpanded, // Variable height
需要再设置高度之前设置该属性;
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 10.0) {
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeCompact;
}
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);
}
模式改变后会执行下面这个方法:
-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize{
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
NSLog(@"maxSize-%@",NSStringFromCGSize(maxSize));// maxSize-{359, 110}
}else{
NSLog(@"maxSize-%@",NSStringFromCGSize(maxSize));// maxSize-{359, 616}
}
}
两种设计风格:
iPhone 7的界面效果
iPhone 6(iOS8.4)的界面效果
扩展:
注意:有人看到这种界面可能会想到tableview实现,开始小编也是这样想的。可是实现起来发现布局都是乱的(具体原因没有找出来,如哪位研究出来了,麻烦交流一下)!所以建议大家使用UIView就可以了!
网络请求数据:
@try { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *param = [[NSMutableDictionary alloc] init];
[param setObject:@"gettopics" forKey:@"action"];
[param setObject:@"135644452322" forKey:@"EchoToken"];
[param setValue:@"data" forKeyPath:@"type"];
[param setValue:[NSString stringWithFormat:@"%i",widgetCount] forKeyPath:@"pagesize"];
[param setValue:@"1" forKeyPath:@"pageindex"];
[param setValue:@"" forKeyPath:@"username"];
[param setValue:@"cF54141DC1FA8E736B45244428874CE46==" forKeyPath:@"token"];
NSDictionary *headers = @{@"Content-Type":@"application/json; charset=utf-8",
@"Accept":@"application/json"
};
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:[@"v1/api.ashx?action=" stringByAppendingString:@"gettopics"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
request.HTTPBody = [[NSString stringWithFormat:@"type=data&pagesize=%i&pageindex=1",widgetCount ] dataUsingEncoding:NSUTF8StringEncoding];
request.allHTTPHeaderFields = headers;
request.HTTPMethod = @"POST";
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
request.HTTPBody = jsonData;
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSError *jsonError = nil;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if (!jsonError) {
NSMutableArray *mutArr = [NSMutableArray array];
for (NSDictionary *dict in jsonDict[@"list"]) {
WGTopic *topic = [[WGTopic alloc] initWithDict:dict];
[mutArr addObject:topic];
}
self.hotTopicArr = mutArr;
}
}];
// 启动任务
[dataTask resume];
dispatch_async(dispatch_get_main_queue(), ^{
[self.view layoutIfNeeded];
});
});
} @catch (NSException *exception) {
} @finally {
}
如果是http请求需要配置info.plist文件:
注意:从2017年1月起所有请求需要时https 的,否则审核就会被拒!web连接可以是http的,但是也需要配置!
APP数据互通:
通过一下沙盒存储方法存储数据和获取数据!
与app使用相同的方法文件:
将公共的文件打包成framework之后,进行相关的配置;
调试:
选择不同的项目运行,在相应的项目里的断点就会起作用!
本文demo
补充:widget的上线也是需要单独申请APP ID的 需要配置证书和Provisioning Profiles文件!
没有配置相关证书时:
配置证书及描述文件:(列举一些)
证书与描述文件配置好之后:
微信号:CocoaChinabbs
▲长按二维码“识别”关注即可免费学习 iOS 开发
月薪十万、出任CEO、赢娶白富美、走上人生巅峰不是梦
--------------------------------------
商务合作QQ:2408167315
投稿邮箱:[email protected]