概述
当前版本:2.2.1.3
发版时间:2019年09月24
文档最后更新时间:2019年09月25日
常见问题请移步至「对接问题」
崩溃问题请移步至「崩溃问题」
版本更新:所有版本通用方式——替换SDK静态库, 删除旧版本SDK所有相关的`.framework``.bundle`文件,清除缓存,再导入新版SDK中的所有`.framework``.bundle`文件(.bundle文件注意保留开发者自定义资源),详细说明请移步至「升级指南」
如需SDK及相关文档下载请移步至「SDK资源下载」
一.准备工作
前置条件
- 闪验SDK支持Xcode 9.4.1,iOS8.0+及以上版本。
- 闪验SDK支持中国移动、联通、电信4G的取号能力。
- 闪验SDK支持网络环境为
a.纯数据网络
b.数据网络与wifi网络双开
- 对于双卡手机,闪验SDK取当前流量卡号
创建应用
提示:一个应用对应一个appid,多个应用(不同bundleID)需在闪验平台创建多个应用以对应多个appid
应用的创建流程及APPID/APPKEY的获取,请查看「账号创建」文档
快速体验Demo
将创建应用时获得的AppID、AppKey填入Demo工程中.pch文件,修改工程BundleID为创建应用时绑定的BundleID即可
开发环境搭建
闪验SDK提供两种集成方式供iOS开发者选择:
- 通过CocoaPods自动集成
- 手动集成
通过CocoaPods自动集成
在工程的Podfile
里面添加以下代码:以下示例pod 版本仅供参考,请按需选择或选择最新版本
#以下三种版本选择方式示例 #集成最新版闪验SDK: pod 'CL_ShanYanSDK' #集成指定版本闪验SDK: pod 'CL_ShanYanSDK', '2.2.1.3' #集成指定版本闪验SDK,并在末位小版本范围更新: pod 'CL_ShanYanSDK', '~> 2.2.1.3'
保存并执行pod install
,然后用后缀为.xcworkspace
的文件打开工程。
注意:
命令行下执行pod search CL_ShanYanSDK
,如显版本不是最新版,或者pod install导入的版本不是最新版,则先执行pod repo update
操作更新本地repo的内容
关于CocoaPods
的更多信息请查看 CocoaPods官方网站。
手动集成
- 导入framework: 将闪验SDK压缩包中framework文件夹下所有资源添加到工程中(注意勾选Copy items if needed)
- Xcode配置:
- OtherLinkerFlags中 添加**-ObjC**:xcode->BuildSetting->Other Linker Flags 添加 **-ObjC**
- 添加libc++.1.tbd: 在xcode->General->Linked Frameworks and Libraries中点击 **+** ,搜索并选择添加 **libc++.1.tbd**
- Swift工程需要额外添加-force_load:
- 在xcode->BuildSetting->Other Linker Flags 添加-force_load
- 在-force_load下方添加CL_ShanYanSDK.framework/CL_ShanYanSDK所在路径,具体操作可以将CL_ShanYanSDK.framework拖入空栏,在尾部拼接静态库名称CL_ShanYanSDK,将前缀绝对地址改成相对地址$(SRCROOT),最终为 "$(SRCROOT)/.../CL_ShanYanSDK.framework/CL_ShanYanSDK"形式
二.SDK使用说明
1.初始化
方法原型
/**初始化*/ +(void)initWithAppId:(NSString *)appId AppKey:(NSString *)appKey complete:(nullable CLComplete)complete;
参数描述
参数 | 是否必填 | 类型 | 说明 |
appId | 必填 | NSString | 闪验appID |
appKey | 必填 | NSString | 闪验appKey |
complete | 选填 | CLComplete | 初始化回调block,可以在此回调block中接收初始化情况,也可以不关心初始化结果 |
接口作用
初始化SDK :传入用户的appID、appKey,获取本机运营商,读取缓存,获取运营商配置,初始化SDK
使用场景
- 建议在app启动时调用
- 必须在一键登录前至少调用一次
- 只需调用一次,多次调用不会多次初始化,与一次调用效果一致
请求示例代码
ObjC:
- 导入闪验SDK头文件
#import <CL_ShanYanSDK/CL_ShanYanSDK.h>
- 在AppDelegate中的
didFinishLaunchingWithOptions
方法中添加初始化代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... //初始化 [CLShanYanSDKManager initWithAppId:cl_SDK_APPID AppKey:cl_SDK_APPKEY complete:nil]; ... }
Swift:
- 创建混编桥接头文件并导入闪验SDK头文件
#import <CL_ShanYanSDK/CL_ShanYanSDK.h>
- 在AppDelegate中的
didFinishLaunchingWithOptions
方法中添加初始化代码
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 建议先检测APP登录状态,未登录再使用闪验 ... //初始化 CLShanYanSDKManager.initWithAppId("your appID", appKey: "your appKey") ... }
2.预取号
不建议频繁的多次调用和在拉起授权页后调用
方法原型
/** * 预取号(获取临时凭证) * 建议在判断当前用户属于未登录状态时使用,已登录状态用户请不要调用该方法 */ +(void)preGetPhonenumber:(nullable CLComplete)complete;
接口作用
电信、联通、移动预取号 :初始化成功后,如果当前为电信/联通/移动,将调用预取号,可以提前获知当前用户的手机网络环境是否符合一键登录的使用条件,成功后将得到用于一键登录使用的临时凭证,默认的凭证有效期60s(电信)/30min(联通)/60min(移动)。
使用场景
- 建议在执行一键登录的方法前,提前一段时间调用此方法,比如调一键登录的vc的viewdidload中,或者rootVC的viewdidload中,或者app启动后,此调用将有助于提高闪验拉起授权页的速度和成功率
- 不建议调用后立即调用拉起授权页方法(此方法是异步)
- 此方法需要1~2s的时间取得临时凭证,因此也不建议和拉起授权页方法一起串行调用
- 不建议频繁的多次调用和在拉起授权页后调用
- 建议在判断当前用户属于未登录状态时使用,已登录状态用户请不要调用该方法
请求示例代码
ObjC:
//开发者调拉起授权页的vc @implementation CustomLoginViewController - (void)viewDidLoad { [super viewDidLoad]; if (YourAppLoginStatus == NO) { //预取号 [CLShanYanSDKManager preGetPhonenumber:nil]; ... } } ... //拉起授权页 - (void)shanYanAuthPageLogin{ ... }
3.拉起授权页
在预取号成功后调用,预取号失败不建议调用。调用拉起授权页方法后将会调起运营商授权页面。该方法会拉起登录界面,已登录状态请勿调用 。
//闪验一键登录接口 +(void)quickAuthLoginWithConfigure:(CLUIConfigure *)clUIConfigure openLoginAuthListener:(CLComplete)openLoginAuthListener oneKeyLoginListener:(CLComplete)oneKeyLoginListener;
参数描述
参数 | 类型 | 说明 |
clUIConfigure 必填 | CLUIConfigure | 授权页控件属性配置对象 |
openLoginAuthListener 选填 | CLComplete | 拉起授权页的回调,拉起页面成功失败均触发 |
oneKeyLoginListener 必填 | CLComplete | 一键登录回调,用于接收一键登录的结果,点一键登录成功失败均触发,点自带的返回按钮也触发 |
使用场景
- 用户进行一键登录操作时,调用一键登录方法,如果初始化成功,SDK将会拉起授权页面,用户授权后,SDK将返回取号 token给到应用客户端。
- 可以在多处调用
- 需在调用预初始化方法之后调用
一键登录逻辑说明
- 存在调用预初始化时获取的临时凭证,调用一键登录方法将立即拉起授权页面
- openLoginAuthListener 拉起授权页监听回调,拉起成功或失败均触发
- 不存在临时凭证或临时凭证过期时(临时凭证有效期电信60s、联通30min、移动60min),调用一键登录方法,将有一个很短的时延,待取号成功后拉起授权页面
- 取号失败时,返回失败
请求示例代码
ObjC:
- 导入闪验SDK头文件
#import <CL_ShanYanSDK/CL_ShanYanSDK.h>
- 在需要使用一键登录的地方调用闪验一键登录接口
// 用户需要使用闪验一键登录时的方法 - (void)quickLoginBtnClick:(UIButton *)sender { __weak typeof(self) weakself = self; CGFloat screenScale = [UIScreen mainScreen].bounds.size.width/375.0; CLUIConfigure * baseUIConfigure = [CLUIConfigure new]; baseUIConfigure.viewController = self; baseUIConfigure.clLogoImage = [UIImage imageNamed:@"your_app_logo_image"]; baseUIConfigure.clAppPrivacyFirst = @[@"闪验测试连接1",[NSURL URLWithString:@"https://baidu.com"]]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"ShanYanIndex" ofType:@"html"]; //baseUIConfigure.clAppPrivacySecond = @[@"闪验测试连接2",[NSURL URLWithString:@"https://sina.com"]]; baseUIConfigure.clAppPrivacySecond = @[@"本地协议地址",[NSURL fileURLWithPath:filePath]]; //layout 布局 CLOrientationLayOut * clOrientationLayOutPortrait = [CLOrientationLayOut new]; clOrientationLayOutPortrait.clLayoutPhoneCenterY = @(0*screenScale); clOrientationLayOutPortrait.clLayoutPhoneLeft = @(50*screenScale); ... baseUIConfigure.clOrientationLayOutPortrait = clOrientationLayOutPortrait; //开发者自己的loading(注意后面loading的隐藏时机) [SVProgressHUD setContainerView:self.view]; [SVProgressHUD show]; //闪验一键登录接口(将拉起授权页) [CLShanYanSDKManager quickAuthLoginWithConfigure:baseUIConfigure openLoginAuthListener:^(CLCompleteResult * _Nonnull completeResult) { [SVProgressHUD hide]; if (completeResult.error) { //拉起授权页失败 NSLog(@"openLoginAuthListener:%@",completeResult.error.userInfo); }else{ //拉起授权页成功 NSLog(@"openLoginAuthListener:%@",completeResult.yy_modelToJSONObject); } } oneKeyLoginListener:^(CLCompleteResult * _Nonnull completeResult) { __strong typeof(self) strongSelf = weakSelf; [SVProgressHUD hide]; if (completeResult.error) { //一键登录失败 NSLog(@"oneKeyLoginListener:%@",completeResult.error.description); //提示:错误无需提示给用户,可以在用户无感知的状态下直接切换登录方式 if (completeResult.code == 1011){ //用户取消登录(点返回) //处理建议:如无特殊需求可不做处理,仅作为交互状态回调,此时已经回到当前用户自己的页面 //点击sdk自带的返回,无论是否设置手动销毁,授权页面都会强制关闭 } else{ //处理建议:其他错误代码表示闪验通道无法继续,可以统一走开发者自己的其他登录方式,也可以对不同的错误单独处理 //1003 一键登录获取token失败 //1008 未开启移动网络 //1009 未检测到sim卡 //其他 其他错误// //关闭授权页,如果授权页还未拉起,此调用不会关闭当前用户vc,即不执行任何代码 [CLShanYanSDKManager finishAuthControllerCompletion:nil]; } }else{ //一键登录获取Token成功 NSLog(@"oneKeyLoginListener:%@",completeResult.yy_modelDescription); //SDK成功获取到Token /** token置换手机号 code */ } }]; }
一键登录 quickAuthLoginWith:complete:
正确返回示例
completeResult->_data: { accessToken = 2ebf48fbe75a45449ed78ecca9c5d93c; appId = xxxxxx; device = ZGV2aWNlPWlQaG9uZTd8aXA9MTcyLjE2LjExLjZ8RElEPTBkOGY2NzViZjdkYjRjZDdmMWI1YmM5NDI3NWIyZTQ0fHV1aWQ9MzBjZGU2ZTktYzZmOS00MGNhLTk4MjEtMzI4NGM0ZDViZDNj; randoms = "321bfcdb-bb34-4e3e-bbf7-def83d33bd76"; sign = "sNeHtWihz7B4iTY1Fch5+ztllDA="; telecom = CTCC; timestamp = 1558771442361; version = "2.2.0"; }
字段 | 类型 | 含义 |
appId | String | 当前项目的appid |
accessToken | String | token,置换令牌,用来和后台置换手机号。一次有效,有效期3min |
telecom | String | 当前数据流量卡的运营商类型: CMCC 移动 CTCC 电信 CUCC 联通 |
timestamp | String | 网络时间 |
randoms | String | 随机数 |
version | String | 后台接口版本号 |
sign | String | 签名 |
device | String | 设备型号 |
ps:请注意返回字段中的accessToken、sign、device字段值为base64字符串,其中包含特殊字符,在客户APP与客户后台交互时应避免使用URL拼接字符串的传值方式,会导致特殊字符丢失,最终导致请求闪验后台的置换手机号接口报“请求非法,签名校验不通过”。
一键登录 quickAuthLoginWith:complete:
报错处理
completeResult->_error:
- 用户取消登录(授权页点击返回) 【处理建议:若无特殊需求可不做处理】
- 用户选择其他方式登录(点击授权页自带的其他方式登录): 【处理建议:可根据实际情况跳转其他登录方式 】
- 其他错误 【处理建议:使用闪验通道失败,可根据实际情况跳转其他登录方式 】
授权页销毁
注:sdk拉起授权页成功后,只允许点击一次一键登录按钮。一键登录按钮点击一次后,只有sdk自带的左上角返回按钮可以交互,效果为强制关闭授权页,其他页面元素均会被禁用,以防止多次点击导致多次回调而出现异常。
拉起授权页前 配置授权页面销毁机制属性
// 获取默认参数配置 CLUIConfigure * baseUIConfigure = [CLUIConfigure clDefaultUIConfigure]; baseUIConfigure.viewController = self; // 是否需要手动销毁授权页面,默认自动销毁, YES->手动销毁 baseUIConfigure.manualDismiss = @(YES);
sdk获取token回调后销毁界面
//关闭页面 [CLShanYanSDKManager finishAuthControllerCompletion:^{ //如需关闭后present/push新页面,建议在completion回调中执行 //注:若未拉起授权页,调用此方法,block不会触发 //用户跳转短信验证 CustomSmsViewController * smsVc = [[CustomSmsViewController alloc]init]; CustomNavigationController * smsNav = [[CustomNavigationController alloc]initWithRootViewController:smsVc]; smsVc.navigationItem.title = @"短信验证"; [self presentViewController:smsNav animated:YES completion:nil]; }];
4.置换手机号
注:移动、联通、电信分别有自己的置换手机号url,需要根据相对应的运营商url置换手机号码。详情见下方 请求示例代码
使用场景
SDK成功返回token后,开发者需自行调用置换手机号接口,此接口需要开发者调用由服务端接入闪验服务端生成的接口,上线前的调试阶段可以直接使用示例代码中的接口
请求示例代码
ObjC:
[CLShanYanSDKManager quickAuthLoginWithConfigure:baseUIConfigure openLoginAuthListener:^(CLCompleteResult * _Nonnull completeResult) { [SVProgressHUD hide]; if (completeResult.error) { //拉起授权页失败 NSLog(@"openLoginAuthListener:%@",completeResult.error.userInfo); }else{ //拉起授权页成功 NSLog(@"openLoginAuthListener:%@",completeResult.yy_modelToJSONObject); } } oneKeyLoginListener:^(CLCompleteResult * _Nonnull completeResult) { [SVProgressHUD dismiss]; if (completeResult.error) { ... }else{ //SDK成功获取到Token NSString * telecom = [completeResult.data valueForKey:@"telecom"]; //urlStr:用户后台对接闪验后台后配置的API,以下为Demo提供的调试API及调用示例,在调试阶段可暂时调用此API,也可用此API验证后台API是否正确配置 NSString * urlStr = nil; if ([telecom isEqualToString:@"CMCC"]) { urlStr = [cl_SDK_URL stringByAppendingString:@"open/flashsdk/mobile-query-m"]; }else if ([telecom isEqualToString:@"CUCC"]) { urlStr = [cl_SDK_URL stringByAppendingString:@"open/flashsdk/mobile-query-u"]; }else if ([telecom isEqualToString:@"CTCC"]) { urlStr = [cl_SDK_URL stringByAppendingString:@"open/flashsdk/mobile-query-t"]; }else{ //失败 return; } if (urlStr) { NSLog(@"tokenParamr:%@",completeResult.data); [NetWorkManager POST_url:urlStr withParameter:completeResult.data complete:^(NSDictionary * _Nonnull responseObject, NSError * _Nonnull error) { if (error) { NSLog(@"%@",error); }else{ NSInteger code = [[responseObject valueForKey:@"code"] integerValue]; if (code == 200000) { NSString * mobileName = responseObject[@"data"][@"mobileName"]; NSString * mobileCode = [mobileName decryptUseDESKey:cl_SDK_APPKEY]; dispatch_async(dispatch_get_main_queue(), ^{ [SVProgressHUD showSuccessWithStatus:[NSString stringWithFormat:@"免密登录成功,手机号:%@",mobileCode]]; }); NSLog(@"免密登录成功,手机号:%@",mobileCode); } else { dispatch_async(dispatch_get_main_queue(), ^{ [SVProgressHUD showSuccessWithStatus:[NSString stringWithFormat:@"免密登录失败"]]; }); NSLog(@"免密登录失败:%@",responseObject); } } }]; } } }];
Swift:
CLShanYanSDKManager.quickAuthLogin(with: clUIConfigure, openLoginAuthListener: { (completeResult) in ... }) { (completeResult) in if completeResult.error != nil { ... }else{ //SDK成功获取到Token NSLog("quickAuthLogin Success:%@",completeResult.data ?? "") //urlStr:用户后台对接闪验后台后配置的API,以下为Demo提供的调试API及调用示例,在调试阶段可暂时调用此API,也可用此API验证后台API是否正确配置 var urlStr : String? let APIString = "https://api.253.com/" if let telecom = completeResult.data?["telecom"] as! String?{ switch telecom { case "CMCC": urlStr = APIString.appendingFormat("open/flashsdk/mobile-query-m") break case "CUCC": urlStr = APIString.appendingFormat("open/flashsdk/mobile-query-u") break case "CTCC": urlStr = APIString.appendingFormat("open/flashsdk/mobile-query-t") break default: break } } if let urlStr = urlStr{ let dataDict = completeResult.data as! Parameters Alamofire.request(urlStr, method:.post, parameters:dataDict, encoding:URLEncoding.default, headers:[:]).responseJSON(completionHandler: { (response) in if response.result.isSuccess { if let json = response.result.value{ let jsonDict = JSON(json) if jsonDict["code"].intValue == 200000{ let mobileName = jsonDict["data"]["mobileName"].stringValue let mobileCode = StringDecryptUseDES.decryptUseDESString(mobileName, key: "tDo3Ml2K")//appKey DispatchQueue.main.async(execute: { SVProgressHUD.showSuccess(withStatus: ("免密登录成功,手机号:\(mobileCode)")) }) print(("免密登录成功,手机号:\(mobileCode)")) return; } } } DispatchQueue.main.async(execute: { SVProgressHUD.showInfo(withStatus: ("免密登录失败:\(response.description)")) print(("免密登录失败:\(response.description)")) }) }) } } } }
token置换手机号 正确返回示例
{ "chargeStatus": 1, "message": "成功", "data": { "fanqizha": "1", "tag": "", "tradeNo": "18112115031414011", "mobileName": "OaLj8kkXPwFGp/eRk+3vQQ\u003d\u003d" }, "code": "200000" }
字段 | 类型 | 含义 |
code | string | 200000成功,其他失败 |
chargeStatus | string | 1:收费 0:不收费 |
tradeNo | string | 交易流水号 |
mobileName | string | DES加密的真实手机号,使用CBC模式,PKCS5Padding填充原则。CBC模式对应的iv偏移向量为:byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 },key为appKey |
fanqizha/tag | string | 防羊毛识别标识,此功能需要在后台开通 fanqizha:int 1:白名单 2:黑名单 3:可信任度低 4:未找到 tag:标签属性,判断的依据信息,用于黑名单。样例:批量操作/系统环境异常/信用低/小号养号/号码风险模型评分中/可能存在作弊行为 |
5.手动关闭授权页
当开发者设置点击一键登录或者自定义控件不自动销毁授权页时,将需要自行调用此方法主动销毁授权页,建议在置换手机号成功后销毁。如在得到回调后未销毁授权页而,使用拉起授权页方法再次拉起授权页,此页面将无法响应任何按键(除了导航栏的返回按钮)。
- 关闭授权页时机
a.SDK拉起授权页方法 直接回调失败时
b.置换手机号有返回结果时
- 当前页面直接销毁
//方式1 [self.PresentedViewController dismissViewControllerAnimated:YES completion:nil]; //方式二 [CLShanYanSDKManager finishAuthControllerCompletion:^{ //如需关闭后present/push新页面,建议在completion回调中执行 //注:若未拉起授权页,调用此方法,block不会触发 //用户跳转短信验证 CustomSmsViewController * smsVc = [[CustomSmsViewController alloc]init]; CustomNavigationController * smsNav = [[CustomNavigationController alloc]initWithRootViewController:smsVc]; smsVc.navigationItem.title = @"短信验证"; [self presentViewController:smsNav animated:YES completion:nil]; }];
- 找到topVC进行dismiss
dispatch_async(dispatch_get_main_queue(), ^{ //建议使用授权页面配置对象传入的viewcontroller 调 dismiss if (self.navigationController.viewControllers.lastObject.navigationController) { [self.navigationController.viewControllers.lastObject dismissViewControllerAnimated:YES completion:nil]; } else { UIViewController *topRootViewController = [[UIApplication sharedApplication] keyWindow].rootViewController; // 在这里加一个这个样式的循环 while (topRootViewController.presentedViewController) { // 这里固定写法 topRootViewController = topRootViewController.presentedViewController; } // 然后再进行present操作 [topRootViewController dismissViewControllerAnimated:YES completion:nil]; } });
6.协议点击监听
iOS协议点击的监听是通过代理实现,在授权页面显示前触发代理进行监听。不监听协议点击可不实现代理,按需配置。
注意实现协议:@interface xxxController ()<CLShanYanSDKManagerDelegate>
在拉起授权页之前设置代理
//弹窗添加蒙版或点击协议回调 代理设置,不监听协议点击或不使用蒙版可不设置代理 [CLShanYanSDKManager setCLShanYanSDKManagerDelegate:self];
回调监听示例,按需实现监听、统计等
- (void)clShanYanSDKManagerWebPrivacyClicked:(NSString *)privacyName privacyIndex:(NSInteger)index currentTelecom:(NSString *)telecom{ NSLog(@"协议名称:%@---协议位置:%lu---当前运营商:%@",privacyName,index,telecom); }
三.授权界面修改
1.设计规范
开发者不得通过任何技术手段,将授权页面的隐私栏、品牌露出内容隐藏、覆盖,对于接入闪验SDK并上线的应用,我方和运营商会对上线的应用授权页面做审查,如果有出现未按要求设计授权页面,将隐私栏、运营商品牌、授权登录按钮隐去不可见的设计,我方有权将应用的登录功能下线。
2.页面可调整属性
注:授权页基本控件均支持上、下、左、右、宽、高、水平中心、竖直中心布局设置,布局通过布局对象设置,布局定位更加方便快捷,建议使用最新布局对象进行设置。
//要拉起授权页的vc [必填项] (注:SDK不持有接入方VC) @property (nonatomic,weak)UIViewController * viewController; /** *外部手动管理关闭界面 *BOOL,default is NO *eg.@(YES) */ @property (nonatomic,strong)NSNumber * manualDismiss; /**授权页-背景图片*/ @property (nonatomic,strong) UIImage *clBackgroundImg; //导航栏 /**导航栏 是否隐藏 BOOL default is NO, 设置优先级高于clNavigationBackgroundClear eg.@(NO)*/ @property (nonatomic,strong)NSNumber * clNavigationBarHidden; /**导航栏 背景透明 BOOL eg.@(YES)*/ @property (nonatomic,strong)NSNumber * clNavigationBackgroundClear; /**导航栏标题*/ @property (nonatomic,strong)NSAttributedString * clNavigationAttributesTitleText; /**导航栏右侧自定义按钮*/ @property (nonatomic,strong)UIBarButtonItem * clNavigationRightControl; /**导航栏左侧自定义按钮*/ @property (nonatomic,strong)UIBarButtonItem * clNavigationLeftControl; // 返回按钮 /**导航栏左侧返回按钮图片*/ @property (nonatomic,strong)UIImage * clNavigationBackBtnImage; /**导航栏自带返回按钮隐藏,默认显示 BOOL eg.@(YES)*/ @property (nonatomic,strong)NSNumber * clNavigationBackBtnHidden; /**************新增******************/ /**返回按钮图片缩进 btn.imageInsets = UIEdgeInsetsMake(0, 0, 20, 20)*/ @property (nonatomic,strong)NSValue * clNavBackBtnImageInsets; /**自带返回(关闭)按钮位置 默认NO 居左,设置为YES居右显示*/ @property (nonatomic,strong)NSNumber * clNavBackBtnAlimentRight; /*translucent 此属性已失效*/ //@property (nonatomic,strong)NSNumber * cl_navigation_translucent; /**导航栏分割线 是否隐藏 * set backgroundImage=UIImage.new && shadowImage=UIImage.new * BOOL, default is NO * eg.@(YES) */ @property (nonatomic,strong)NSNumber * clNavigationBottomLineHidden; /**导航栏 文字颜色*/ @property (nonatomic,strong)UIColor * clNavigationTintColor; /**导航栏 背景色 default is white*/ @property (nonatomic,strong)UIColor * clNavigationBarTintColor; /**导航栏 背景图片*/ @property (nonatomic,strong)UIImage * clNavigationBackgroundImage; /**导航栏 配合背景图片设置,用来控制在不同状态下导航栏的显示(横竖屏是否显示) UIBarMetrics eg.@(UIBarMetricsCompact)*/ @property (nonatomic,strong)NSNumber * clNavigationBarMetrics; /**导航栏 导航栏底部分割线(图片)*/ @property (nonatomic,strong)UIImage * clNavigationShadowImage; /*状态栏样式 *Info.plist: View controller-based status bar appearance = YES * *UIStatusBarStyleDefault:状态栏显示 黑 *UIStatusBarStyleLightContent:状态栏显示 白 *UIStatusBarStyleDarkContent:状态栏显示 黑 API_AVAILABLE(ios(13.0)) = 3 **eg. @(UIStatusBarStyleLightContent) */ @property (nonatomic,strong)NSNumber * clPreferredStatusBarStyle; /*状态栏隐藏 eg.@(NO)*/ @property (nonatomic,strong)NSNumber * clPrefersStatusBarHidden; /** *NavigationBar.barStyle:默认UIBarStyleBlack *Info.plist: View controller-based status bar appearance = YES *UIBarStyleDefault:状态栏显示 黑 *UIBarStyleBlack:状态栏显示 白 * *eg. @(UIBarStyleBlack) */ @property (nonatomic,strong)NSNumber * clNavigationBarStyle; //LOGO图片 /**LOGO图片*/ @property (nonatomic,strong)UIImage * clLogoImage; /**LOGO圆角 CGFloat eg.@(2.0)*/ @property (nonatomic,strong)NSNumber * clLogoCornerRadius; /**LOGO显隐 BOOL eg.@(NO)*/ @property (nonatomic,strong)NSNumber * clLogoHiden; /**手机号显示控件*/ /**手机号颜色*/ @property (nonatomic,strong)UIColor * clPhoneNumberColor; /**手机号字体*/ @property (nonatomic,strong)UIFont * clPhoneNumberFont; /**手机号对齐方式 NSTextAlignment eg.@(NSTextAlignmentCenter)*/ @property (nonatomic,strong)NSNumber * clPhoneNumberTextAlignment; /*一键登录按钮 控件 注: 一键登录授权按钮 不得隐藏 **/ /**按钮文字*/ @property (nonatomic,copy)NSString * clLoginBtnText; /**按钮文字颜色*/ @property (nonatomic,strong)UIColor * clLoginBtnTextColor; /**按钮背景颜色*/ @property (nonatomic,strong)UIColor * clLoginBtnBgColor; /**按钮文字字体*/ @property (nonatomic,strong)UIFont * clLoginBtnTextFont; /**按钮背景图片*/ @property (nonatomic,strong)UIImage * clLoginBtnNormalBgImage; /**按钮背景高亮图片*/ @property (nonatomic,strong)UIImage * clLoginBtnHightLightBgImage; /**按钮边框颜色*/ @property (nonatomic,strong)UIColor * clLoginBtnBorderColor; /**按钮圆角 CGFloat eg.@(5)*/ @property (nonatomic,strong)NSNumber * clLoginBtnCornerRadius; /**按钮边框 CGFloat eg.@(2.0)*/ @property (nonatomic,strong)NSNumber * clLoginBtnBorderWidth; /*隐私条款Privacy 注: 运营商隐私条款 不得隐藏 用户条款不限制 **/ /**隐私条款名称颜色:@[基础文字颜色UIColor*,条款颜色UIColor*] eg.@[[UIColor lightGrayColor],[UIColor greenColor]]*/ @property (nonatomic,strong) NSArray<UIColor*> *clAppPrivacyColor; /**隐私条款文字字体*/ @property (nonatomic,strong)UIFont * clAppPrivacyTextFont; /**隐私条款文字对齐方式 NSTextAlignment eg.@(NSTextAlignmentCenter)*/ @property (nonatomic,strong)NSNumber * clAppPrivacyTextAlignment; /**运营商隐私条款书名号 默认NO 不显示 BOOL eg.@(YES)*/ @property (nonatomic,strong)NSNumber * clAppPrivacyPunctuationMarks; /**多行时行距 CGFloat eg.@(2.0)*/ @property (nonatomic,strong)NSNumber* clAppPrivacyLineSpacing; /**是否需要sizeToFit,设置后与宽高约束的冲突请自行考虑 BOOL eg.@(YES)*/ @property (nonatomic,strong)NSNumber* clAppPrivacyNeedSizeToFit; /**隐私条款--APP名称简写 默认取CFBundledisplayname 设置描述文本四后此属性无效*/ @property (nonatomic,copy) NSString * clAppPrivacyAbbreviatedName; /* *隐私条款Y一:需同时设置Name和UrlString eg.@[@"条款一名称",条款一URL] *@[NSSting,NSURL]; */ @property (nonatomic,strong)NSArray * clAppPrivacyFirst; /* *隐私条款二:需同时设置Name和UrlString eg.@[@"条款一名称",条款一URL] *@[NSSting,NSURL]; */ @property (nonatomic,strong)NSArray * clAppPrivacySecond; /* 隐私协议文本拼接: DesTextFirst+运营商条款+DesTextSecond+隐私条款一+DesTextThird+隐私条款二+DesTextFourth **/ /**描述文本一 default:"同意"*/ @property (nonatomic,copy)NSString *clAppPrivacyNormalDesTextFirst; /**描述文本二 default:"和"*/ @property (nonatomic,copy)NSString *clAppPrivacyNormalDesTextSecond; /**描述文本三 default:"、"*/ @property (nonatomic,copy)NSString *clAppPrivacyNormalDesTextThird; /**描述文本四 default: "并授权AppName使用认证服务"*/ @property (nonatomic,copy)NSString *clAppPrivacyNormalDesTextFourth; /**用户隐私协议WEB页面导航栏标题 默认显示用户条款名称*/ @property (nonatomic,strong)NSAttributedString * clAppPrivacyWebAttributesTitle; /**运营商隐私协议WEB页面导航栏标题 默认显示运营商条款名称*/ @property (nonatomic,strong)NSAttributedString * clAppPrivacyWebNormalAttributesTitle; /**隐私协议WEB页面导航返回按钮图片*/ @property (nonatomic,strong)UIImage * clAppPrivacyWebBackBtnImage; /*状态栏样式 默认:UIStatusBarStyleDefault*/ @property (nonatomic,strong)NSNumber * clAppPrivacyWebPreferredStatusBarStyle; /*SLOGAN 注: 运营商品牌标签("中国**提供认证服务"),不得隐藏 **/ /**slogan文字字体*/ @property (nonatomic,strong) UIFont * clSloganTextFont; /**slogan文字颜色*/ @property (nonatomic,strong) UIColor * clSloganTextColor; /**slogan文字对齐方式 NSTextAlignment eg.@(NSTextAlignmentCenter)*/ @property (nonatomic,strong) NSNumber * clSlogaTextAlignment; /*CheckBox *协议勾选框,默认选中且在协议前显示 *可在sdk_oauth.bundle中替换checkBox_unSelected、checkBox_selected图片 *也可以通过属性设置选中和未选择图片 **/ /**协议勾选框(默认显示,放置在协议之前)BOOL eg.@(YES)*/ @property (nonatomic,strong) NSNumber *clCheckBoxHidden; /**协议勾选框默认值(默认不选中)BOOL eg.@(YES)*/ @property (nonatomic,strong) NSNumber *clCheckBoxValue; /**协议勾选框 尺寸 NSValue->CGSize eg.[NSValue valueWithCGSize:CGSizeMake(25, 25)]*/ @property (nonatomic,strong) NSValue *clCheckBoxSize; /**协议勾选框 UIButton.image图片缩进 UIEdgeInset eg.[NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(2, 2, 2, 2)]*/ @property (nonatomic,strong) NSValue *clCheckBoxImageEdgeInsets; /**协议勾选框 设置CheckBox顶部与隐私协议控件顶部对齐 YES或大于0生效 eg.@(YES)*/ @property (nonatomic,strong) NSNumber *clCheckBoxVerticalAlignmentToAppPrivacyTop; /**协议勾选框 设置CheckBox顶部与隐私协议控件竖向中心对齐 YES或大于0生效 eg.@(YES)*/ @property (nonatomic,strong) NSNumber *clCheckBoxVerticalAlignmentToAppPrivacyCenterY; /**协议勾选框 非选中状态图片*/ @property (nonatomic,strong) UIImage *clCheckBoxUncheckedImage; /**协议勾选框 选中状态图片*/ @property (nonatomic,strong) UIImage *clCheckBoxCheckedImage; /*Loading*/ /**Loading 大小 CGSize eg.[NSValue valueWithCGSize:CGSizeMake(50, 50)]*/ @property (nonatomic,strong) NSValue *clLoadingSize; /**Loading 圆角 float eg.@(5) */ @property (nonatomic,strong) NSNumber *clLoadingCornerRadius; /**Loading 背景色 UIColor eg.[UIColor colorWithRed:0.8 green:0.5 blue:0.8 alpha:0.8]; */ @property (nonatomic,strong) UIColor *clLoadingBackgroundColor; /**UIActivityIndicatorViewStyle eg.@(UIActivityIndicatorViewStyleWhiteLarge)*/ @property (nonatomic,strong) NSNumber *clLoadingIndicatorStyle; /**Loading Indicator渲染色 UIColor eg.[UIColor greenColor]; */ @property (nonatomic,strong) UIColor *clLoadingTintColor; /**授权页自定义Loading - containerView为loading的全屏蒙版view - 请自行在containerView添加自定义loading - 设置block后,上述loading属性将无效 */ @property (nonatomic,copy)void(^loadingView)(UIView * containerView); //添加自定义控件 /**可设置背景色及添加控件*/ @property (nonatomic,copy)void(^customAreaView)(UIView * customAreaView); /**横竖屏*/ /*是否支持自动旋转 BOOL*/ @property (nonatomic,strong) NSNumber * shouldAutorotate; /*支持方向 UIInterfaceOrientationMask - 如果设置只支持竖屏,只需设置clOrientationLayOutPortrait竖屏布局对象 - 如果设置只支持横屏,只需设置clOrientationLayOutLandscape横屏布局对象 - 横竖屏均支持,需同时设置clOrientationLayOutPortrait和clOrientationLayOutLandscape */ @property (nonatomic,strong) NSNumber * supportedInterfaceOrientations; /*默认方向 UIInterfaceOrientation*/ @property (nonatomic,strong) NSNumber * preferredInterfaceOrientationForPresentation; /**以窗口方式显示授权页 */ /**以窗口方式显示 BOOL, default is NO */ @property (nonatomic,strong) NSNumber * clAuthTypeUseWindow; /**窗口圆角 float*/ @property (nonatomic,strong) NSNumber * clAuthWindowCornerRadius; /**clAuthWindowModalTransitionStyle系统自带的弹出方式 仅支持以下三种 UIModalTransitionStyleCoverVertical 底部弹出 UIModalTransitionStyleCrossDissolve 淡入 UIModalTransitionStyleFlipHorizontal 翻转显示 */ @property (nonatomic,strong) NSNumber * clAuthWindowModalTransitionStyle; /* UIModalPresentationStyle * 若使用窗口模式,请设置为UIModalPresentationOverFullScreen 或不设置 * iOS13强制全屏,请设置为UIModalPresentationFullScreen * UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2 * eg. @(UIModalPresentationOverFullScreen) */ @property (nonatomic,strong) NSNumber * clAuthWindowModalPresentationStyle; /**弹窗的MaskLayer,用于自定义窗口形状*/ @property (nonatomic,strong) CALayer * clAuthWindowMaskLayer; //竖屏布局配置对象 -->创建一个布局对象,设置好控件约束属性值,再设置到此属性中 /**竖屏:UIInterfaceOrientationPortrait|UIInterfaceOrientationPortraitUpsideDown *eg. CLUIConfigure * baseUIConfigure = [CLUIConfigure new]; * CLOrientationLayOut * clOrientationLayOutPortrait = [CLOrientationLayOut new]; * clOrientationLayOutPortrait.clLayoutPhoneCenterY = @(0); * clOrientationLayOutPortrait.clLayoutPhoneLeft = @(50*screenScale); * ... * baseUIConfigure.clOrientationLayOutPortrait = clOrientationLayOutPortrait; */ @property (nonatomic,strong) CLOrientationLayOut * clOrientationLayOutPortrait; //横屏布局配置对象 -->创建一个布局对象,设置好控件约束属性值,再设置到此属性中 /**横屏:UIInterfaceOrientationLandscapeLeft|UIInterfaceOrientationLandscapeRight *eg. CLUIConfigure * baseUIConfigure = [CLUIConfigure new]; * CLOrientationLayOut * clOrientationLayOutLandscape = [CLOrientationLayOut new]; * clOrientationLayOutLandscape.clLayoutPhoneCenterY = @(0); * clOrientationLayOutLandscape.clLayoutPhoneLeft = @(50*screenScale); * ... * baseUIConfigure.clOrientationLayOutLandscape = clOrientationLayOutLandscape; */ @property (nonatomic,strong) CLOrientationLayOut * clOrientationLayOutLandscape; /**默认界面配置*/ + (CLUIConfigure *)clDefaultUIConfigure; @end /**横竖屏布局配置对象 配置页面布局相关属性 */ @interface CLOrientationLayOut : NSObject /**LOGO图片*/ // 约束均相对vc.view @property (nonatomic,strong)NSNumber * clLayoutLogoLeft; @property (nonatomic,strong)NSNumber * clLayoutLogoTop; @property (nonatomic,strong)NSNumber * clLayoutLogoRight; @property (nonatomic,strong)NSNumber * clLayoutLogoBottom; @property (nonatomic,strong)NSNumber * clLayoutLogoWidth; @property (nonatomic,strong)NSNumber * clLayoutLogoHeight; @property (nonatomic,strong)NSNumber * clLayoutLogoCenterX; @property (nonatomic,strong)NSNumber * clLayoutLogoCenterY; /**手机号显示控件*/ //layout 约束均相对vc.view @property (nonatomic,strong)NSNumber * clLayoutPhoneLeft; @property (nonatomic,strong)NSNumber * clLayoutPhoneTop; @property (nonatomic,strong)NSNumber * clLayoutPhoneRight; @property (nonatomic,strong)NSNumber * clLayoutPhoneBottom; @property (nonatomic,strong)NSNumber * clLayoutPhoneWidth; @property (nonatomic,strong)NSNumber * clLayoutPhoneHeight; @property (nonatomic,strong)NSNumber * clLayoutPhoneCenterX; @property (nonatomic,strong)NSNumber * clLayoutPhoneCenterY; /*一键登录按钮 控件 注: 一键登录授权按钮 不得隐藏 **/ //layout 约束均相对vc.view @property (nonatomic,strong)NSNumber * clLayoutLoginBtnLeft; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnTop; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnRight; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnBottom; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnWidth; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnHeight; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnCenterX; @property (nonatomic,strong)NSNumber * clLayoutLoginBtnCenterY; /*隐私条款Privacy 注: 运营商隐私条款 不得隐藏, 用户条款不限制 **/ //layout 约束均相对vc.view @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyLeft; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyTop; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyRight; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyBottom; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyWidth; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyHeight; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyCenterX; @property (nonatomic,strong)NSNumber * clLayoutAppPrivacyCenterY; /*Slogan 运营商品牌标签:"认证服务由中国移动/联通/电信提供" label 注: 运营商品牌标签,不得隐藏 **/ //layout 约束均相对vc.view @property (nonatomic,strong)NSNumber * clLayoutSloganLeft; @property (nonatomic,strong)NSNumber * clLayoutSloganTop; @property (nonatomic,strong)NSNumber * clLayoutSloganRight; @property (nonatomic,strong)NSNumber * clLayoutSloganBottom; @property (nonatomic,strong)NSNumber * clLayoutSloganWidth; @property (nonatomic,strong)NSNumber * clLayoutSloganHeight; @property (nonatomic,strong)NSNumber * clLayoutSloganCenterX; @property (nonatomic,strong)NSNumber * clLayoutSloganCenterY; /**窗口模式*/ /**窗口中心:CGPoint X Y*/ @property (nonatomic,strong) NSValue * clAuthWindowOrientationCenter; /**窗口左上角:frame.origin:CGPoint X Y*/ @property (nonatomic,strong) NSValue * clAuthWindowOrientationOrigin; /**窗口大小:宽 float */ @property (nonatomic,strong) NSNumber * clAuthWindowOrientationWidth; /**窗口大小:高 float */ @property (nonatomic,strong) NSNumber * clAuthWindowOrientationHeight; /**默认布局配置*/ + (CLOrientationLayOut *)clDefaultOrientationLayOut;
3.横竖屏设置
相关设置属性
/**横竖屏*/ /*是否支持自动旋转 BOOL*/ @property (nonatomic,strong) NSNumber * shouldAutorotate; /*支持方向 UIInterfaceOrientationMask - 如果设置只支持竖屏,只需设置clOrientationLayOutPortrait竖屏布局对象 - 如果设置只支持横屏,只需设置clOrientationLayOutLandscape横屏布局对象 - 横竖屏均支持,需同时设置clOrientationLayOutPortrait和clOrientationLayOutLandscape */ @property (nonatomic,strong) NSNumber * supportedInterfaceOrientations; /*默认方向 UIInterfaceOrientation*/ @property (nonatomic,strong) NSNumber * preferredInterfaceOrientationForPresentation;
使用示例代码-请下载demo查看详细配置
- (CLUIConfigure *)configureStyle3:(CLUIConfigure *)inputConfigure{ CGFloat screenWidth_Portrait; CGFloat screenHeight_Portrait; CGFloat screenWidth_Landscape; CGFloat screenHeight_Landscape; UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) { screenWidth_Portrait = UIScreen.mainScreen.bounds.size.width; screenHeight_Portrait = UIScreen.mainScreen.bounds.size.height; screenWidth_Landscape = UIScreen.mainScreen.bounds.size.height; screenHeight_Landscape = UIScreen.mainScreen.bounds.size.width; }else{ screenWidth_Portrait = UIScreen.mainScreen.bounds.size.height; screenHeight_Portrait = UIScreen.mainScreen.bounds.size.width; screenWidth_Landscape = UIScreen.mainScreen.bounds.size.width; } ..... }
4.弹窗模式设置
4.1 相关设置属性
/**以窗口方式显示授权页 */ /**以窗口方式显示 BOOL, default is NO */ @property (nonatomic,strong) NSNumber * clAuthTypeUseWindow; /**窗口圆角 float*/ @property (nonatomic,strong) NSNumber * clAuthWindowCornerRadius; /**clAuthWindowModalTransitionStyle系统自带的弹出方式 仅支持以下三种 UIModalTransitionStyleCoverVertical 底部弹出 UIModalTransitionStyleCrossDissolve 淡入 UIModalTransitionStyleFlipHorizontal 翻转显示 */ @property (nonatomic,strong) NSNumber * clAuthWindowModalTransitionStyle; /**弹窗的MaskLayer,用于自定义窗口形状*/ @property (nonatomic,strong) CALayer * clAuthWindowMaskLayer;
4.2 布局示例代码
详细请下载demo查看配置
- (CLUIConfigure *)configureStyle3:(CLUIConfigure *)inputConfigure{ CGFloat screenWidth_Portrait; CGFloat screenHeight_Portrait; CGFloat screenWidth_Landscape; CGFloat screenHeight_Landscape; UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) { screenWidth_Portrait = UIScreen.mainScreen.bounds.size.width; screenHeight_Portrait = UIScreen.mainScreen.bounds.size.height; screenWidth_Landscape = UIScreen.mainScreen.bounds.size.height; screenHeight_Landscape = UIScreen.mainScreen.bounds.size.width; }else{ screenWidth_Portrait = UIScreen.mainScreen.bounds.size.height; screenHeight_Portrait = UIScreen.mainScreen.bounds.size.width; screenWidth_Landscape = UIScreen.mainScreen.bounds.size.width; screenHeight_Landscape = UIScreen.mainScreen.bounds.size.height; } CGFloat screenScale = [UIScreen mainScreen].bounds.size.width/375.0; if (screenScale > 1) { screenScale = 1; } CLUIConfigure * baseUIConfigure = inputConfigure; baseUIConfigure.clCheckBoxValue = @(YES); //横竖屏旋转方向设置 baseUIConfigure.shouldAutorotate = @(YES); baseUIConfigure.supportedInterfaceOrientations = @(UIInterfaceOrientationMaskAll); //baseUIConfigure.preferredInterfaceOrientationForPresentation = @(UIInterfaceOrientationLandscapeLeft); //使用窗口方式 baseUIConfigure.clAuthTypeUseWindow = @(YES); baseUIConfigure.clAuthWindowCornerRadius = @(20); baseUIConfigure.clAuthWindowModalTransitionStyle = @(UIModalTransitionStyleCoverVertical); /****页面元素配置****/ baseUIConfigure.clBackgroundImg = [UIImage imageNamed:@"eb9a0dae18491990a43fe02832d3cafa"]; baseUIConfigure.clNavigationBackgroundClear = @(YES); baseUIConfigure.clNavigationBackBtnHidden = @(YES); baseUIConfigure.clNavigationBottomLineHidden = @(YES); // 自定义协议加载 baseUIConfigure.clAppPrivacyFirst = @[@"闪验测试连接1",[NSURL URLWithString:@"https://baidu.com"]]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"ShanYanIndex" ofType:@"html"]; //baseUIConfigure.clAppPrivacySecond = @[@"闪验测试连接2",[NSURL URLWithString:@"https://sina.com"]]; baseUIConfigure.clAppPrivacySecond = @[@"本地协议地址",[NSURL fileURLWithPath:filePath]]; ... /****横竖屏布局配置****/ //布局-竖屏 CLOrientationLayOut * clOrientationLayOutPortrait = [CLOrientationLayOut new]; //窗口中心 clOrientationLayOutPortrait.clAuthWindowOrientationCenter = [NSValue valueWithCGPoint:CGPointMake(screenWidth_Portrait*0.5, screenHeight_Portrait*0.5)]; //窗口宽高 CGFloat authWindowWidth_Portrait = screenWidth_Portrait * 0.8;//窗口宽度为竖屏宽度的0.8 CGFloat authWindowHeight_Portrait = authWindowWidth_Portrait * 0.8;//窗口高度为窗口宽度的0.8 clOrientationLayOutPortrait.clAuthWindowOrientationWidth = @(authWindowWidth_Portrait); clOrientationLayOutPortrait.clAuthWindowOrientationHeight = @(authWindowHeight_Portrait); clOrientationLayOutPortrait.clLayoutLogoWidth = @(60*screenScale); clOrientationLayOutPortrait.clLayoutLogoHeight = @(60*screenScale); clOrientationLayOutPortrait.clLayoutLogoCenterX = @(0); clOrientationLayOutPortrait.clLayoutLogoTop = @(25*screenScale); clOrientationLayOutPortrait.clLayoutPhoneCenterY = @(-20*screenScale); clOrientationLayOutPortrait.clLayoutPhoneLeft = @(50*screenScale); clOrientationLayOutPortrait.clLayoutPhoneRight = @(-50*screenScale); clOrientationLayOutPortrait.clLayoutPhoneHeight = @(20*screenScale); clOrientationLayOutPortrait.clLayoutLoginBtnCenterY= @(clOrientationLayOutPortrait.clLayoutPhoneCenterY.floatValue + clOrientationLayOutPortrait.clLayoutPhoneHeight.floatValue*0.5*screenScale + 20*screenScale + 15*screenScale); clOrientationLayOutPortrait.clLayoutLoginBtnHeight = @(30*screenScale); clOrientationLayOutPortrait.clLayoutLoginBtnLeft = @(70*screenScale); clOrientationLayOutPortrait.clLayoutLoginBtnRight = @(-70*screenScale); clOrientationLayOutPortrait.clLayoutAppPrivacyLeft = @(40*screenScale); clOrientationLayOutPortrait.clLayoutAppPrivacyRight = @(-40*screenScale); clOrientationLayOutPortrait.clLayoutAppPrivacyBottom = @(0*screenScale); clOrientationLayOutPortrait.clLayoutAppPrivacyHeight = @(45*screenScale); clOrientationLayOutPortrait.clLayoutSloganLeft = @(0); clOrientationLayOutPortrait.clLayoutSloganRight = @(0); clOrientationLayOutPortrait.clLayoutSloganHeight = @(15*screenScale); clOrientationLayOutPortrait.clLayoutSloganBottom = @(clOrientationLayOutPortrait.clLayoutAppPrivacyBottom.floatValue - clOrientationLayOutPortrait.clLayoutAppPrivacyHeight.floatValue); //布局-横屏 CLOrientationLayOut * clOrientationLayOutLandscape = [CLOrientationLayOut new]; //窗口中心 clOrientationLayOutLandscape.clAuthWindowOrientationCenter = [NSValue valueWithCGPoint:CGPointMake(screenWidth_Landscape*0.5, screenHeight_Landscape*0.5)]; //窗口宽高 CGFloat authWindowWidth_Landscape = screenWidth_Portrait * 0.8;//窗口宽度为竖屏宽度的0.8 CGFloat authWindowHeight_Landscape = authWindowWidth_Landscape * 0.8;//窗口高度为窗口宽度的0.8 clOrientationLayOutLandscape.clAuthWindowOrientationWidth = @(authWindowWidth_Landscape); clOrientationLayOutLandscape.clAuthWindowOrientationHeight = @(authWindowHeight_Landscape); clOrientationLayOutLandscape.clLayoutLogoWidth = @(60*screenScale); clOrientationLayOutLandscape.clLayoutLogoHeight = @(60*screenScale); clOrientationLayOutLandscape.clLayoutLogoCenterX = @(0); clOrientationLayOutLandscape.clLayoutLogoTop = @(25*screenScale); clOrientationLayOutLandscape.clLayoutPhoneCenterY = @(-20*screenScale); clOrientationLayOutLandscape.clLayoutPhoneLeft = @(50*screenScale); clOrientationLayOutLandscape.clLayoutPhoneRight = @(-50*screenScale); clOrientationLayOutLandscape.clLayoutPhoneHeight = @(20*screenScale); clOrientationLayOutLandscape.clLayoutLoginBtnCenterY= @(clOrientationLayOutLandscape.clLayoutPhoneCenterY.floatValue + clOrientationLayOutLandscape.clLayoutPhoneHeight.floatValue*0.5*screenScale + 20*screenScale + 15*screenScale); clOrientationLayOutLandscape.clLayoutLoginBtnHeight = @(30*screenScale); clOrientationLayOutLandscape.clLayoutLoginBtnLeft = @(70*screenScale); clOrientationLayOutLandscape.clLayoutLoginBtnRight = @(-70*screenScale); clOrientationLayOutLandscape.clLayoutAppPrivacyLeft = @(40*screenScale); clOrientationLayOutLandscape.clLayoutAppPrivacyRight = @(-40*screenScale); clOrientationLayOutLandscape.clLayoutAppPrivacyBottom = @(0*screenScale); clOrientationLayOutLandscape.clLayoutAppPrivacyHeight = @(45*screenScale); clOrientationLayOutLandscape.clLayoutSloganLeft = @(0); clOrientationLayOutLandscape.clLayoutSloganRight