授权页面 UI 修改

最近更新时间:2020-06-10 17:40:20

目录

1、设计规范

授权页面 UI 修改

2、页面控件位置大小设置

金山云支持两种方式设置授权页面控件的位置和大小:

  • 设置控件的 KOLRect 属性,通过设置控件距离屏幕顶部和屏幕左边的偏移量来控制控件的位置,通过设置控件的宽高来控制控件的大小
  • 在回调中拿到授权页面所有控件,通过 masnory 或其他方式进行自动布局

2.1、 设置控件的 KOLRect 属性

/**
 * @abstract 1、若授权页面只支持竖屏,只设置竖屏方向偏移;
             2、若授权页面只支持横屏,只设置横屏方向偏移;
             3、若授权页面支持旋转自动切换横竖屏,则同时设置竖屏方向和横屏方向偏移
             4、弹窗模式,同以上1、2、3
             5、size默认都可以不用设置,会根据字体大小自适应
             6、x轴方向偏移量有两个值可以设置,portraitCenterXOffset为控件的x轴中点到弹窗x轴中点的距离,portraitLeftXOffset为控件的左边缘到屏幕左边缘的距离,两者选其一即可
 */
typedef struct KOLRect {
    /**
     竖屏时
     导航栏隐藏时,为控件顶部到状态栏的距离;导航栏显示时,为控件顶部到导航栏底部的距离
     弹窗时
     为控件顶部到弹窗顶部的距离
     */
    CGFloat portraitTopYOffset;

    /**
     竖屏时
     控件的x轴中点到屏幕x轴中点的距离,默认为0
     弹窗时
     控件的x轴中点到弹窗x轴中点的距离,默认为0
     */
    CGFloat portraitCenterXOffset;

    /**
     竖屏时
     控件的左边缘到屏幕左边缘的距离,默认为0
     弹窗时
     控件的左边缘到屏幕左边缘的距离,默认为0

     portraitLeftXOffset与portraitCenterXOffset设置一个即可,portraitLeftXOffset优先级大于portraitCenterXOffset,
     设置此属性时,portraitCenterXOffset属性失效
     */
    CGFloat portraitLeftXOffset;

    /**
     横屏时
     导航栏隐藏时,为控件顶部到屏幕顶部的距离;导航栏显示时,为控件顶部到导航栏底部的距离
     弹窗时
     为控件顶部到弹窗顶部的距离
     */
    CGFloat landscapeTopYOffset;

    /**
     横屏时
     控件的x轴中点到屏幕x轴中点的距离,默认为0
     弹窗时
     控件的x轴中点到弹窗x轴中点的距离,默认为0
     */
    CGFloat landscapeCenterXOffset;

    /**
     横屏时
     控件的左边缘到屏幕左边缘的距离,默认为0
     弹窗时
     控件的左边缘到屏幕左边缘的距离,默认为0

     landscapeLeftXOffset与landscapeCenterXOffset设置一个即可,landscapeLeftXOffset优先级大于landscapeCenterXOffset,
     设置此属性时,landscapeCenterXOffset属性失效
     */
    CGFloat landscapeLeftXOffset;

    /**
     控件大小,只有宽度、高度同时大于0,设置的size才会生效,否则为控件默认的size
     */
    CGSize size;
} KOLRect;

/**
 返回按钮位置及大小,返回按钮最大size为CGSizeMake(40, 40)。
 */
@property (nonatomic, assign) KOLRect backButtonRect;

/**
 Logo 位置及大小。
 */
@property (nonatomic, assign) KOLRect logoRect;

/**
 号码预览 位置及大小
 */
@property (nonatomic, assign) KOLRect phoneNumRect;

/**
 授权页切换账号按钮 位置及大小。
 */
@property (nonatomic, assign) KOLRect switchButtonRect;

/**
 授权按钮 位置及大小。
 */
@property (nonatomic, assign) KOLRect authButtonRect;

/**
 Slogan 位置及大小。
 */
@property (nonatomic, assign) KOLRect sloganRect;

/**
 授权页面上条款勾选框大小及位置。
 */
@property (nonatomic, assign) KOLRect checkBoxRect;

/**
 隐私条款 位置及大小,隐私条款,宽需大于50,高需大于20,才会生效。
 */
@property (nonatomic, assign) KOLRect termsRect;

/**
 弹窗 位置及大小。弹窗模式时,x轴偏移只支持portraitLeftXOffset和landscapeLeftXOffset。
 */
@property (nonatomic, assign) KOLRect popupRect;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置控件的 KOLRect 属性
KOLRect backButtonRect = {0, 0, 0, 0, 0, 0, {0, 0}}; // 返回按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.backButtonRect = backButtonRect;

KOLRect logoRect = {0, 0, 0, 20, 0, 0, {0, 0}}; // logo偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置,logo大小默认为图片大小
viewModel.logoRect = logoRect;

KOLRect phoneNumRect = {0, 0, 0, 0, 0, 0, {0, 0}};  // 手机号偏移设置
viewModel.phoneNumRect = phoneNumRect;

KOLRect switchButtonRect = {0, 0, 0, 0, 0, 0, {0, 0}};  // 切换按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.switchButtonRect = switchButtonRect;

KOLRect authButtonRect = {0, 0, 0, 0, 0, 0, {300, 40}};  // 授权按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.authButtonRect = authButtonRect;

KOLRect sloganRect = {0, 0, 0, 0, 0, 0, {0, 0}};  // slogan偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.sloganRect = sloganRect;

KOLRect checkBoxRect = {0, 0, 0, 0, 0, 0, {12, 12}};
viewModel.checkBoxRect = checkBoxRect; // 复选框尺寸,默认为12*12

KOLRect termsRect = {0, 0, 0, 0, 0, 0, {0, 0}};  // 服务条款偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.termsRect = termsRect;

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置控件的 KOLRect 属性
let backButtonRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0)) // 返回按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.backButtonRect = backButtonRect

let logoRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 20, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0)) // logo偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置,logo大小默认为图片大小
viewModel.logoRect = logoRect

let phoneNumRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0)) // 手机号偏移设置
viewModel.phoneNumRect = phoneNumRect

let switchButtonRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0))  // 切换按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.switchButtonRect = switchButtonRect

let authButtonRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 300, height: 40)) // 授权按钮偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.authButtonRect = authButtonRect

let sloganRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0))  // slogan偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.sloganRect = sloganRect

let checkBoxRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 12, height: 12)) // 复选框尺寸,默认为12*12
viewModel.checkBoxRect = checkBoxRect

let termsRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0))  // 服务条款偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.termsRect = termsRect

2.2、控件进行自动布局

/**
 * @abstract 授权页面视图控件自动布局回调,可在该回调中,对控件通过 masonry 或者其他方式进行自动布局,若需要自定义视图,请直接在该回调中添加,实现该回调后,授权页面所有视图的约束都会被删除,您需要重新设置所有视图的约束
 *
 * authView 为 authContentView 的父视图
 * authContentView 为 authBackgroundImageView、authNavigationView、authLogoView、authPhoneView、authSwitchButton、authLoginButton、authSloganView、authAgreementView、authClosePopupButton 的父视图
 * authNavigationView 为 authNavigationContainerView 的父视图
 * authNavigationContainerView 为 authBackButton 和 authNavigationTitleView 的父视图
 * authAgreementView 为 authCheckbox 和 authProtocolView 的父视图
 *
 */
typedef void(^OLAuthVCAutoLayoutBlock)(UIView *authView, UIView *authContentView, UIView *authBackgroundImageView, UIView *authNavigationView, UIView *authNavigationContainerView, UIView *authBackButton, UIView *authNavigationTitleView, UIView *authLogoView, UIView *authPhoneView, UIView *authSwitchButton, UIView *authLoginButton, UIView *authSloganView, UIView *authAgreementView, UIView *authCheckbox, UIView *authProtocolView, UIView *authClosePopupButton);

/**
 * 授权页面视图控件自动布局回调
 */
@property (nullable, nonatomic, copy) OLAuthVCAutoLayoutBlock autolayoutBlock;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 通过回调对控件进行自动布局
viewModel.autolayoutBlock = ^(UIView *authView, UIView *authContentView, UIView *authBackgroundImageView, UIView *authNavigationView, UIView *authNavigationContainerView, UIView *authBackButton, UIView *authNavigationTitleView, UIView *authLogoView, UIView *authPhoneView, UIView *authSwitchButton, UIView *authLoginButton, UIView *authSloganView, UIView *authAgreementView, UIView *authCheckbox, UIView *authProtocolView, UIView *authClosePopupButton) {
    // content
    [authContentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(authView);
    }];

    // background
    [authBackgroundImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(authContentView);
    }];

    // navigation
    [authNavigationView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.right.equalTo(authContentView);
        make.height.mas_equalTo(64);
    }];

    [authNavigationContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(authNavigationView);
    }];

    [authBackButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(authNavigationContainerView).offset(20);
        make.centerY.equalTo(authNavigationContainerView).offset(10);
        make.size.mas_equalTo(CGSizeMake(20, 20));
    }];

    [authNavigationTitleView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authNavigationContainerView);
        make.centerY.equalTo(authNavigationContainerView).offset(10);
        make.size.mas_equalTo(CGSizeMake(100, 40));
    }];

    UIButton *rightBarButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [rightBarButton setTitle:@"完成" forState:UIControlStateNormal];
    [rightBarButton addTarget:self action:@selector(doneAction:) forControlEvents:UIControlEventTouchUpInside];
    [authNavigationContainerView addSubview:rightBarButton];
    [rightBarButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(authNavigationContainerView).offset(-10);
        make.centerY.equalTo(authNavigationContainerView).offset(10);
        make.size.mas_equalTo(CGSizeMake(60, 40));
    }];

    // logo
    [authLogoView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authContentView);
        make.top.equalTo(authNavigationView.mas_bottom).offset(100);
        make.size.mas_equalTo(CGSizeMake(107, 22));
    }];

    // phone
    [authPhoneView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authContentView);
        make.top.equalTo(authLogoView.mas_bottom).offset(20);
        make.size.mas_equalTo(CGSizeMake(200, 40));
    }];

    // switchbutton
    [authSwitchButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authContentView);
        make.top.equalTo(authPhoneView.mas_bottom).offset(20);
        make.size.mas_equalTo(CGSizeMake(200, 20));
    }];

    // loginbutton
    [authLoginButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authContentView);
        make.top.equalTo(authSwitchButton.mas_bottom).offset(30);
        make.size.mas_equalTo(CGSizeMake(260, 40));
    }];

    // slogan
    [authSloganView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(authContentView);
        make.top.equalTo(authLoginButton.mas_bottom).offset(20);
        make.size.mas_equalTo(CGSizeMake(260, 20));
    }];

    // agreementview
    [authAgreementView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(authContentView).offset(20);
        make.right.equalTo(authContentView).offset(-20);
        make.top.equalTo(authSloganView.mas_bottom).offset(50);
        make.height.mas_equalTo(80);
    }];

    [authCheckbox mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(authAgreementView).offset(10);
        make.top.equalTo(authAgreementView).offset(10);
    }];

    [authProtocolView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(authCheckbox.mas_right).offset(5);
        make.right.equalTo(authAgreementView).offset(-10);
        make.height.equalTo(authAgreementView);
    }];

    // 自定义视图
    UIButton *customBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    [customBtn setTitle:@"我是自定义UI" forState:UIControlStateNormal];
    customBtn.backgroundColor = [UIColor lightGrayColor];
    customBtn.layer.cornerRadius = 2.0;
    [customBtn addTarget:self action:@selector(dismissAuthVC) forControlEvents:UIControlEventTouchUpInside];
    [authContentView addSubview:customBtn];
    [customBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(authContentView).offset(20);
        make.right.equalTo(authContentView).offset(-20);
        make.height.mas_equalTo(40);
        make.top.equalTo(authAgreementView.mas_bottom).offset(30);
    }];
};

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 通过回调对控件进行自动布局
viewModel.autolayoutBlock = { [weak self] (authView: UIView, authContentView: UIView, authBackgroundImageView: UIView, authNavigationView: UIView, authNavigationContainerView: UIView, authBackButton: UIView, authNavigationTitleView: UIView, authLogoView: UIView, authPhoneView: UIView, authSwitchButton: UIView, authLoginButton: UIView, authSloganView: UIView, authAgreementView: UIView, authCheckbox: UIView, authProtocolView: UIView, authClosePopupButton: UIView) in
    // content
    authContentView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.edges.equalTo()(authView)
    }

    // background
    authBackgroundImageView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.edges.equalTo()(authContentView)
    }

    // navigation
    authNavigationView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.top().right().equalTo()(authContentView)
        make?.height.mas_equalTo()(64)
    }

    authNavigationContainerView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.edges.equalTo()(authNavigationView)
    }

    authBackButton.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.equalTo()(authNavigationContainerView)?.offset()(20)
        make?.centerY.equalTo()(authNavigationContainerView)?.offset()(10)
        make?.size.mas_equalTo()(CGSize.init(width: 20, height: 20))
    }

    authNavigationTitleView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authNavigationContainerView)
        make?.centerY.equalTo()(authNavigationContainerView)?.offset()(10)
        make?.size.mas_equalTo()(CGSize.init(width: 100, height: 40))
    }

    // 导航栏右侧控制视图
    let strongSelf = self
    let rightBarButton = UIButton.init(type: UIButton.ButtonType.custom)
    rightBarButton.setTitle("完成", for: UIControl.State.normal)
    rightBarButton.addTarget(strongSelf, action: #selector(strongSelf?.doneAction), for: UIControl.Event.touchUpInside)
    authNavigationContainerView.addSubview(rightBarButton)
    rightBarButton.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.right.equalTo()(authNavigationContainerView)?.offset()(-10)
        make?.centerY.equalTo()(authNavigationContainerView)?.offset()(10)
        make?.size.mas_equalTo()(CGSize.init(width: 60, height: 40))
    }

    // logo
    authLogoView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authContentView)
        make?.top.equalTo()(authNavigationView.mas_bottom)?.offset()(100)
        make?.size.mas_equalTo()(CGSize.init(width: 107, height: 22))
    }

    // phone
    authPhoneView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authContentView)
        make?.top.equalTo()(authLogoView.mas_bottom)?.offset()(20)
        make?.size.mas_equalTo()(CGSize.init(width: 200, height: 40))
    }

    // switchbutton
    authSwitchButton.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authContentView)
        make?.top.equalTo()(authPhoneView.mas_bottom)?.offset()(20)
        make?.size.mas_equalTo()(CGSize.init(width: 200, height: 20))
    }

    // loginbutton
    authLoginButton.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authContentView)
        make?.top.equalTo()(authSwitchButton.mas_bottom)?.offset()(30)
        make?.size.mas_equalTo()(CGSize.init(width: 260, height: 40))
    }

    // slogan
    authSloganView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.centerX.equalTo()(authContentView)
        make?.top.equalTo()(authLoginButton.mas_bottom)?.offset()(20)
        make?.size.mas_equalTo()(CGSize.init(width: 260, height: 20))
    }

    // agreementview
    authAgreementView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.equalTo()(authContentView)?.offset()(20)
        make?.right.equalTo()(authContentView)?.offset()(-20)
        make?.top.equalTo()(authSloganView.mas_bottom)?.offset()(50)
        make?.height.mas_equalTo()(80)
    }

    authCheckbox.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.equalTo()(authAgreementView)?.offset()(10)
        make?.top.equalTo()(authAgreementView)?.offset()(10)
    }

    authProtocolView.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.equalTo()(authCheckbox.mas_right)?.offset()(5)
        make?.right.equalTo()(authAgreementView)?.offset()(-10)
        make?.height.equalTo()(authAgreementView);
    }

    // 自定义视图
    let customBtn = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 40))
    customBtn.setTitle("我是自定义UI", for: UIControl.State.normal)
    customBtn.backgroundColor = UIColor.red
    customBtn.layer.cornerRadius = 2.0
    customBtn.addTarget(strongSelf, action: #selector(strongSelf?.dismissAuthVC), for: UIControl.Event.touchUpInside)
    authContentView.addSubview(customBtn)
    customBtn.mas_makeConstraints { (make: MASConstraintMaker?) in
        make?.left.equalTo()(authContentView)?.offset()(20)
        make?.right.equalTo()(authContentView)?.offset()(-20)
        make?.height.mas_equalTo()(40)
        make?.top.equalTo()(authAgreementView.mas_bottom)?.offset()(30)
    }
}

3、页面控件属性设置

#pragma mark - Status Bar/状态栏

/**
 状态栏样式。 默认 `UIStatusBarStyleDefault`。
 */
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;

#pragma mark - Navigation/导航

/**
 授权页导航的标题。默认为空字符串。
 */
@property (nullable, nonatomic, strong) NSAttributedString *naviTitle;

/**
 授权页导航的背景颜色。默认白色。
 */
@property (nullable, nonatomic, strong) UIColor *naviBgColor;

/**
 授权页导航左边的返回按钮的图片。默认黑色系统样式返回图片。
 */
@property (nullable, nonatomic, strong) UIImage *naviBackImage;

/**
 授权页导航右边的自定义控件。
 */
@property (nullable, nonatomic, strong) UIView *naviRightControl;

/**
 导航栏隐藏。默认不隐藏。
 */
@property (nonatomic, assign) BOOL naviHidden;

/**
 返回按钮隐藏。默认不隐藏。
 */
@property (nonatomic, assign) BOOL backButtonHidden;

#pragma mark - Logo/图标

/**
 授权页面上展示的图标。默认为 "OneLogin" 图标。
 */
@property (nullable, nonatomic, strong) UIImage *appLogo;

/**
 Logo 图片隐藏。默认不隐藏。
 */
@property (nonatomic, assign) BOOL logoHidden;

/**
 logo圆角,默认为0。
 */
@property (nonatomic, assign) CGFloat logoCornerRadius;

#pragma mark - Phone Number Preview/手机号预览

/**
 号码预览文字的颜色。默认黑色。
 */
@property (nullable, nonatomic, strong) UIColor *phoneNumColor;

/**
 号码预览文字的字体。默认粗体,24pt。
 */
@property (nullable, nonatomic, strong) UIFont *phoneNumFont;

#pragma mark - Switch Button/切换按钮

/**
 授权页切换账号按钮的文案。默认为“切换账号”。
 */
@property (nullable, nonatomic, copy) NSString *switchButtonText;

/**
 授权页切换账号按钮的颜色。默认蓝色。
 */
@property (nullable, nonatomic, strong) UIColor *switchButtonColor;

/**
 授权页切换账号按钮背景颜色。默认为 nil。
 */
@property (nullable, nonatomic, strong) UIColor *switchButtonBackgroundColor;

/**
 授权页切换账号的字体。默认字体,15pt。
 */
@property (nullable, nonatomic, strong) UIFont *switchButtonFont;

/**
 隐藏切换账号按钮。默认不隐藏。
 */
@property (nonatomic, assign) BOOL switchButtonHidden;

#pragma mark - Authorization Button/认证按钮

/**
 授权页认证按钮的背景图片, @[正常状态的背景图片, 不可用状态的背景图片, 高亮状态的背景图片]。默认正常状态为蓝色纯色, 不可用状态的背景图片时为灰色, 高亮状态为灰蓝色。
 */
@property (nullable, nonatomic, strong) NSArray<UIImage *> *authButtonImages;

/**
 授权按钮文案。默认白色的"一键登录"。
 */
@property (nullable, nonatomic, strong) NSAttributedString *authButtonTitle;

/**
 授权按钮圆角,默认为0。
 */
@property (nonatomic, assign) CGFloat authButtonCornerRadius;

#pragma mark - Slogan/口号标语

/**
 Slogan 文字颜色。默认灰色。
 */
@property (nonatomic, strong) UIColor *sloganTextColor;

/**
 Slogan字体。默认字体, 12pt。
 */
@property (nonatomic, strong) UIFont *sloganTextFont;

#pragma mark - CheckBox & Privacy Terms/隐私条款勾选框及隐私条款

/**
 授权页面上条款勾选框初始状态。默认 YES。
 */
@property (nonatomic, assign) BOOL defaultCheckBoxState;

/**
 授权页面上勾选框勾选的图标。默认为蓝色图标。推荐尺寸为12x12。
 */
@property (nullable, nonatomic, strong) UIImage *checkedImage;

/**
 授权页面上勾选框未勾选的图标。默认为白色图标。推荐尺寸为12x12。
 */
@property (nullable, nonatomic, strong) UIImage *uncheckedImage;

/**
 隐私条款文字属性。默认基础文字灰色, 条款蓝色高亮, 12pt。
 */
@property (nullable, nonatomic, strong) NSDictionary<NSAttributedStringKey, id> *privacyTermsAttributes;

/**
 额外的条款。默认为空。
 */
@property (nullable, nonatomic, strong) NSArray<KSCPrivacyTermItem *> *additionalPrivacyTerms;

/**
 服务条款普通文字的颜色。默认灰色。
 */
@property (nullable, nonatomic, strong) UIColor *termTextColor;

/**
 除隐私条款外的其他文案,数组大小必须为4,元素依次为:条款前的文案、条款一和条款二连接符、条款二和条款三连接符,条款后的文案。
 默认为@[@"登录即同意", @"和", @"、", @"并使用本机号码登录"]
 */
@property (nullable, nonatomic, copy) NSArray<NSString *> *auxiliaryPrivacyWords;

/**
 * 点击授权页面隐私协议前勾选框的回调
 */
@property (nullable, nonatomic, copy) OLClickCheckboxBlock clickCheckboxBlock;

/**
* 服务条款文案对齐方式,默认为NSTextAlignmentLeft
*/
@property (nonatomic, assign) NSTextAlignment termsAlignment;

#pragma mark - Background Image/授权页面背景图片

/**
 授权页背景颜色。默认白色。
 */
@property (nullable, nonatomic, strong) UIColor *backgroundColor;

/**
 授权页面背景图片
 */
@property (nullable, nonatomic, strong) UIImage *backgroundImage;

/**
 横屏模式授权页面背景图片
 */
@property (nullable, nonatomic, strong) UIImage *landscapeBackgroundImage;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置控件属性
// --------------状态栏设置 -------------------
viewModel.statusBarStyle = UIStatusBarStyleLightContent;

// -------------- 授权页面背景设置 -------------------
viewModel.backgroundColor = UIColor.lightGrayColor;

// -------------- 导航栏设置 -------------------
viewModel.naviTitle = [[NSAttributedString alloc] initWithString:@"一键登录"
                                                      attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,
                                                                   NSFontAttributeName : [UIFont boldSystemFontOfSize:18]
                                                                   }];  // 导航栏标题
viewModel.naviBgColor = UIColor.greenColor; // 导航栏背景色
viewModel.naviBackImage = [UIImage imageNamed:@"back"]; // 导航栏返回按钮
viewModel.backButtonHidden = NO; // 是否隐藏返回按钮,默认不隐藏

// -------------- logo设置 -------------------
viewModel.appLogo = [UIImage imageNamed:@"网关取号_logo"];  // 自定义logo图片
viewModel.logoHidden = NO; // 是否隐藏logo,默认不隐藏
viewModel.logoCornerRadius = 0; // logo圆角,默认为0

// -------------- 手机号设置 -------------------
viewModel.phoneNumColor = UIColor.redColor; // 颜色
viewModel.phoneNumFont = [UIFont boldSystemFontOfSize:25]; // 字体

// -------------- 切换账号设置 -------------------
viewModel.switchButtonColor = UIColor.brownColor; // 切换按钮颜色
viewModel.switchButtonFont = [UIFont systemFontOfSize:15];  // 切换按钮字体
viewModel.switchButtonText = @"自定义切换按钮文案";  // 切换按钮文案
viewModel.switchButtonHidden = NO; // 是否隐藏切换按钮,默认不隐藏

// -------------- 授权登录按钮设置 -------------------
viewModel.authButtonImages = @[
                               [UIImage imageNamed:@"bg_logo_launch"],
                               [UIImage imageNamed:@"bg_logo_launch"],
                               [UIImage imageNamed:@"bg_logo_launch"]
                               ];   // 授权按钮背景图片
viewModel.authButtonTitle = [[NSAttributedString alloc] initWithString:@"授权登录"
                                                            attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,
                                                                         NSFontAttributeName : [UIFont boldSystemFontOfSize:18]
                                                                         }];  // 登录按钮文案
                                                                         viewModel.authButtonRect = authButtonRect;
viewModel.authButtonCornerRadius = 0; // 授权按钮圆角,默认为0
viewModel.clickAuthButtonBlock = ^(void) {  // 点击授权页面登录按钮回调
    NSLog(@"clickAuthButtonBlock");
};

// -------------- slogan设置 -------------------
viewModel.sloganTextColor = UIColor.cyanColor; // slogan颜色
viewModel.sloganTextFont = [UIFont systemFontOfSize:14]; // slogan字体

// -------------- 服务条款设置 -------------------
viewModel.defaultCheckBoxState = YES; // 是否默认选择同意服务条款,默认同意

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置控件属性
// --------------状态栏设置 -------------------
viewModel.statusBarStyle = .lightContent

// -------------- 授权页面背景图片设置 -------------------
viewModel.backgroundColor = .lightGray

// -------------- 导航栏设置 -------------------
viewModel.naviTitle = NSAttributedString.init(string: "一键登录", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 18)]) // 导航栏标题
viewModel.naviBgColor = .green // 导航栏背景色
viewModel.naviBackImage = UIImage.init(named: "back") // 导航栏返回按钮
viewModel.backButtonHidden = false // 是否隐藏返回按钮,默认不隐藏

// -------------- logo设置 -------------------
viewModel.appLogo = UIImage.init(named: "网关取号_logo")
viewModel.logoHidden = false // 是否隐藏logo,默认不隐藏
viewModel.logoCornerRadius = 0

// -------------- 手机号设置 -------------------
viewModel.phoneNumColor = UIColor.red // 颜色
viewModel.phoneNumFont = UIFont.boldSystemFont(ofSize: 25) // 字体

// -------------- 切换账号设置 -------------------
viewModel.switchButtonColor = UIColor.brown // 切换按钮颜色
viewModel.switchButtonFont = UIFont.systemFont(ofSize: 15)  // 切换按钮字体
viewModel.switchButtonText = "自定义切换按钮文案"  // 切换按钮文案
viewModel.switchButtonHidden = false // 是否隐藏切换按钮,默认不隐藏

// -------------- 授权登录按钮设置 -------------------
viewModel.authButtonImages = [(UIImage.init(named: "bg_logo_launch") ?? UIImage.init()), (UIImage.init(named: "bg_logo_launch") ?? UIImage.init()), (UIImage.init(named: "bg_logo_launch") ?? UIImage.init())] // 授权按钮背景图片
viewModel.authButtonTitle = NSAttributedString.init(string: "授权登录", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 18)]) // 登录按钮文案

viewModel.authButtonCornerRadius = 0 // 授权按钮圆角,默认为0
viewModel.clickAuthButtonBlock = { // 点击授权页面登录按钮回调
    print("clickAuthButtonBlock")
}

// -------------- slogan设置 -------------------
viewModel.sloganTextColor = UIColor.cyan // slogan颜色
viewModel.sloganTextFont = UIFont.systemFont(ofSize: 14) // slogan字体

// -------------- 服务条款设置 -------------------
viewModel.defaultCheckBoxState = true

4、横竖屏设置

/**
 * 授权页面支持的横竖屏方向
 */
@property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations;

通过设置 supportedInterfaceOrientations 属性,即可控制授权页面的横竖屏,授权页面可以支持横竖屏自由组合,若设置授权页面同时支持竖屏和横屏,授权页面会跟随设备旋转自动进行横竖屏切换

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置 supportedInterfaceOrientations 属性
// -------------- 授权页面支持的横竖屏设置 -------------------
viewModel.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置 supportedInterfaceOrientations 属性
// -------------- 授权页面支持的横竖屏设置 -------------------
viewModel.supportedInterfaceOrientations = UIInterfaceOrientationMask.allButUpsideDown

5、弹窗模式设置

#pragma mark - Popup

/**
 * 是否为弹窗模式
 */
@property (nonatomic, assign) BOOL isPopup;

/**
 弹窗 位置及大小。弹窗模式时,x轴偏移只支持portraitLeftXOffset和landscapeLeftXOffset。
 */
@property (nonatomic, assign) KOLRect popupRect;

/**
 弹窗圆角,默认为6。
 */
@property (nonatomic, assign) CGFloat popupCornerRadius;

/**
 当只需要设置弹窗的部分圆角时,通过popupCornerRadius设置圆角大小,通过popupRectCorners设置需要设置圆角的位置。
 popupRectCorners数组元素不超过四个,超过四个时,只取前四个。比如,要设置左上和右上为圆角,则传值:@[@(UIRectCornerTopLeft), @(UIRectCornerTopRight)]
 */
@property (nonatomic, strong) NSArray<NSNumber *> *popupRectCorners;

/**
 * 弹窗动画类型,当popupAnimationStyle为OLAuthPopupAnimationStyleStyleCustom时,动画为用户自定义,用户需要传一个CATransition对象来设置动画
 */
@property (nonatomic, assign) OLAuthPopupAnimationStyle popupAnimationStyle;

/**
 * 弹窗自定义动画
 */
@property (nonatomic, strong) CAAnimation *popupTransitionAnimation;

/**
 弹窗关闭按钮图片,弹窗关闭按钮的尺寸跟图片尺寸保持一致。
 弹窗关闭按钮位于弹窗右上角,目前只支持设置其距顶部偏移和距右边偏移。
 */
@property (nullable, nonatomic, strong) UIImage *closePopupImage;

/**
 弹窗关闭按钮距弹窗顶部偏移。
 */
@property (nonatomic, strong) NSNumber *closePopupTopOffset;

/**
 弹窗关闭按钮距弹窗右边偏移。
 */
@property (nonatomic, strong) NSNumber *closePopupRightOffset;

/**
是否需要通过点击弹窗的背景区域以关闭授权页面。
*/
@property (nonatomic, assign) BOOL canClosePopupFromTapGesture;

/**
* 点击授权页面弹窗背景的回调
*/
@property (nonatomic, copy) OLTapAuthBackgroundBlock tapAuthBackgroundBlock;

通过设置 isPopup 属性为 YES,即可以弹窗模式弹出授权页面,可自定义弹窗的大小、弹窗弹出动画形式及弹窗圆角,弹窗中各控件大小、位置、属性的设置同上

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置弹窗
KSCAuthViewModel *viewModel = [KSCAuthViewModel new];
viewModel.isPopup = YES;
viewModel.switchButtonHidden = YES;

// --------------点击弹窗背景收起弹窗 -------------------
viewModel.canClosePopupFromTapGesture = YES;

// -------------- 弹窗设置 -------------------

// 自定义弹窗动画
viewModel.popupAnimationStyle = KSCOLAuthPopupAnimationStyleCoverVertical; // 弹窗动画风格,支持CoverVertical、StyleFlipHorizontal、CrossDissolve和自定义模式,默认为CoverVertical
CATransition *animation = [CATransition animation];
animation.duration = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = @"rippleEffect";
animation.subtype = kCATransitionFromLeft;
viewModel.popupTransitionAnimation = animation; // 只有在popupAnimationStyle为OLAuthPopupAnimationStyleCustom时生效

// 弹窗位置、大小设置,弹窗默认大小为300*340,居于屏幕中间,假如要弹窗居于底部,可做如下设置
KOLRect popupRect = {[self ol_screenHeight] - 340, 0, 0, 0, 0, 0, {[self ol_screenWidth], 340}};  // 弹窗偏移、大小设置
viewModel.popupRect = popupRect;
viewModel.popupCornerRadius = 8; // 弹窗圆角,默认为6
viewModel.popupRectCorners = @[@(UIRectCornerTopLeft), @(UIRectCornerTopRight)];  // 设置部分圆角
viewModel.closePopupImage = [UIImage imageNamed:@"back"]; // 关闭按钮
viewModel.closePopupTopOffset = @(3);  // 关闭按钮距弹窗顶部偏移
viewModel.closePopupRightOffset = @(-8); // 关闭按钮距弹窗右边偏移

viewModel.tapAuthBackgroundBlock = ^{
    NSLog(@"tapAuthBackgroundBlock");
};

__weak typeof(self) wself = self;
// 在SDK内部预取号未成功时,建议加载进度条
if (![KSCOneLoginPro isPrefetchTokenResultValidate]) {

}
// --------------授权页面生命周期回调 -------------------
viewModel.viewLifeCycleBlock = ^(NSString *viewLifeCycle, BOOL animated) {
    NSLog(@"viewLifeCycle: %@, animated: %@", viewLifeCycle, animated ? @"YES" : @"NO");
    if ([viewLifeCycle isEqualToString:@"viewDidDisappear:"]) {

    } else if ([viewLifeCycle isEqualToString:@"viewDidLoad"]) {
        // 授权页面出现时,关掉进度条
    }
};

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置弹窗
let viewModel = KSCAuthViewModel()
// 设置为弹窗模式
viewModel.isPopup = true
// 隐藏切换账号按钮
viewModel.switchButtonHidden = true
// 点击弹窗之外的空白处关闭弹窗
viewModel.canClosePopupFromTapGesture = true

viewModel.tapAuthBackgroundBlock = {
    print("tapAuthBackgroundBlock")
}

viewModel.supportedInterfaceOrientations = UIInterfaceOrientationMask.allButUpsideDown

// -------------- 弹窗设置 -------------------
viewModel.popupAnimationStyle = KSCOLAuthPopupAnimationStyle.coverVertical

let animation = CATransition.init()
animation.duration = 1
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.type = CATransitionType.init(rawValue: "rippleEffect")
animation.subtype = CATransitionSubtype.fromLeft
viewModel.popupTransitionAnimation = animation

let popupRect = KOLRect(portraitTopYOffset: self.ol_screenHeight() - 340, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: self.ol_screenWidth(), height: 340))
viewModel.popupRect = popupRect
viewModel.popupCornerRadius = 5
viewModel.closePopupTopOffset = NSNumber.init(value: 3)  // 关闭按钮距弹窗顶部偏移
viewModel.closePopupRightOffset = NSNumber.init(value: -8)
viewModel.popupRectCorners = [NSNumber.init(value: UIRectCorner.topLeft.rawValue), NSNumber.init(value: UIRectCorner.topRight.rawValue)]

// --------------授权页面生命周期回调 -------------------
viewModel.viewLifeCycleBlock = { (viewLifeCycle : String, animated : Bool) in
    print("viewLifeCycle: %@, animated: %@", viewLifeCycle, animated ? "true" : "false")
    if viewLifeCycle == "viewDidDisappear:" {
        sender.isEnabled = true
    } else if viewLifeCycle == "viewDidLoad" {
        // 授权页面出现时,关掉进度条
        KSCProgressHUD.hideAllHUD()
    }
}

// 进入授权页面

if !KSCOneLoginPro.isPrefetchTokenResultValidate() {
}

KSCOneLoginPro.requestToken(with: self, viewModel: viewModel) { [weak self] result in
    if let strongSelf = self {

    }
}

6、授权页面中添加自定义控件

/**
 * @abstract 授权登录页面自定义视图,customAreaView为授权页面的view,如,可将三方登录添加到授权登录页面
 */
typedef void(^OLCustomUIHandler)(UIView *customAreaView);

/**
 自定义区域视图的处理block

 @discussion
 提供的视图容器使用NSLayoutConstraint与相关的视图进行布局约束。
 如果导航栏没有隐藏, 顶部与导航栏底部对齐, 左边与屏幕左边对齐, 右边与屏幕右边对齐, 底部与屏幕底部对齐。
 如果导航栏隐藏, 顶部与状态栏底部对齐, 左边与屏幕左边对齐, 右边与屏幕右边对齐, 底部与屏幕底部对齐。
 */
@property (nullable, nonatomic, copy) OLCustomUIHandler customUIHandler;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 添加自定义控件
// -------------- 自定义UI设置,如,可以在授权页面添加三方登录入口 -------------------
UIButton *customBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
[customBtn setTitle:@"我是自定义UI" forState:UIControlStateNormal];
customBtn.backgroundColor = [UIColor redColor];
customBtn.layer.cornerRadius = 2.0;
[customBtn addTarget:self action:@selector(dismissAuthVC) forControlEvents:UIControlEventTouchUpInside];
__block CGFloat customAreaWidth = 0;
__block CGFloat customAreaHeight = 0;
viewModel.customUIHandler = ^(UIView * _Nonnull customAreaView) {
    [customAreaView addSubview:customBtn];
    customBtn.center = CGPointMake(customAreaView.bounds.size.width/2, customAreaView.bounds.size.height/2 + 150);
    customAreaWidth = customAreaView.bounds.size.width > customAreaView.bounds.size.height ? customAreaView.bounds.size.height : customAreaView.bounds.size.width;
    customAreaHeight = customAreaView.bounds.size.width < customAreaView.bounds.size.height ? customAreaView.bounds.size.height : customAreaView.bounds.size.width;
};

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 添加自定义控件
// -------------- 自定义UI设置,如,可以在授权页面添加三方登录入口 -------------------
let customBtn = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 40))
customBtn.setTitle("我是自定义UI", for: UIControl.State.normal)
customBtn.backgroundColor = UIColor.red
customBtn.layer.cornerRadius = 2.0
customBtn.addTarget(self, action: #selector(dismissAuthVC), for: UIControl.Event.touchUpInside)

var customAreaWidth = 0.0
var customAreaHeight = 0.0

viewModel.customUIHandler = { (customAreaView: UIView) in
    customAreaView.addSubview(customBtn)
    customBtn.center = CGPoint.init(x: customAreaView.bounds.size.width/2, y: customAreaView.bounds.size.height/2 + 150)
    customAreaWidth = Double(customAreaView.bounds.size.width > customAreaView.bounds.size.height ? customAreaView.bounds.size.height : customAreaView.bounds.size.width)
    customAreaHeight = Double(customAreaView.bounds.size.width < customAreaView.bounds.size.height ? customAreaView.bounds.size.height : customAreaView.bounds.size.width)
}

7、自定义授权页面 loading

/**
 * 授权页自定义Loading,会在点击登录按钮之后触发
 * containerView为loading的全屏蒙版view
 * 请自行在containerView添加自定义loading
 * 设置block后,默认loading将无效
 */
typedef void(^OLLoadingViewBlock)(UIView *containerView);

/**
 * 停止授权页自定义Loading,会在调用[KSCOneLoginPro stopLoading]时触发
 * containerView为loading的全屏蒙版view
 */
typedef void(^OLStopLoadingViewBlock)(UIView *containerView);

/**
 * 授权页面,自定义加载进度条,点击登录按钮之后的回调
 */
@property (nonatomic, copy, nullable) OLLoadingViewBlock loadingViewBlock;

/**
 * 授权页面,停止自定义加载进度条,调用[KSCOneLoginPro stopLoading]之后的回调
 */
@property (nonatomic, copy, nullable) OLStopLoadingViewBlock stopLoadingViewBlock;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 添加自定义 loading
// -------------- 授权页面自动旋转时的回调,在该回调中调整自定义视图的frame,若授权页面不支持自动旋转,或者没有添加自定义视图,可不用实现该block -------------------
viewModel.authVCTransitionBlock = ^(CGSize size, id<UIViewControllerTransitionCoordinator>  _Nonnull coordinator, UIView * _Nonnull customAreaView) {
    if (size.width > size.height) { // 横屏
        customBtn.center = CGPointMake(customAreaHeight/2, customAreaWidth/2 - 15);
    } else {                        // 竖屏
        customBtn.center = CGPointMake(customAreaWidth/2, customAreaHeight/2 + 150);
    }
};

// -------------- 授权页面点击登录按钮之后的loading设置 -------------------
viewModel.loadingViewBlock = ^(UIView * _Nonnull containerView) {
    if ([KSCOneLoginPro isProtocolCheckboxChecked]) {
        UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        [containerView addSubview:indicatorView];
        indicatorView.center = CGPointMake(containerView.bounds.size.width/2, containerView.bounds.size.height/2);
        [indicatorView startAnimating];
    }
};

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 添加自定义 loading
// -------------- 授权页面点击登录按钮之后的loading设置 -------------------
viewModel.loadingViewBlock = { (containerView: UIView) in
    if KSCOneLoginPro.isProtocolCheckboxChecked() {
        let indicatorView = UIActivityIndicatorView.init(style: UIActivityIndicatorView.Style.whiteLarge)
        containerView.addSubview(indicatorView)
        indicatorView.center = CGPoint.init(x: containerView.bounds.size.width/2, y: containerView.bounds.size.height/2)
        indicatorView.startAnimating()
    }
}

viewModel.stopLoadingViewBlock = { (containerView: UIView) in
    for subview in containerView.subviews {
        if subview is UIActivityIndicatorView {
            (subview as! UIActivityIndicatorView).stopAnimating()
            subview.removeFromSuperview()
            break
        }
    }
}

8、设置服务条款

#pragma mark - CheckBox & Privacy Terms/隐私条款勾选框及隐私条款

/**
 授权页面上条款勾选框初始状态。默认 YES。
 */
@property (nonatomic, assign) BOOL defaultCheckBoxState;

/**
 授权页面上勾选框勾选的图标。默认为蓝色图标。推荐尺寸为12x12。
 */
@property (nullable, nonatomic, strong) UIImage *checkedImage;

/**
 授权页面上勾选框未勾选的图标。默认为白色图标。推荐尺寸为12x12。
 */
@property (nullable, nonatomic, strong) UIImage *uncheckedImage;

/**
 授权页面上条款勾选框大小。
 */
@property (nonatomic, assign) CGSize checkBoxSize __attribute__((deprecated("use checkBoxRect instead.")));

/**
 授权页面上条款勾选框大小及位置。
 */
@property (nonatomic, assign) KOLRect checkBoxRect;

/**
 隐私条款文字属性。默认基础文字灰色, 条款蓝色高亮, 12pt。
 */
@property (nullable, nonatomic, strong) NSDictionary<NSAttributedStringKey, id> *privacyTermsAttributes;

/**
 额外的条款。默认为空。
 */
@property (nullable, nonatomic, strong) NSArray<KSCPrivacyTermItem *> *additionalPrivacyTerms;

/**
 服务条款普通文字的颜色。默认灰色。
 */
@property (nullable, nonatomic, strong) UIColor *termTextColor;

/**
 隐私条款 位置及大小,隐私条款,宽需大于50,高需大于20,才会生效。
 */
@property (nonatomic, assign) KOLRect termsRect;

/**
 除隐私条款外的其他文案,数组大小必须为4,元素依次为:条款前的文案、条款一和条款二连接符、条款二和条款三连接符,条款后的文案。
 默认为@[@"登录即同意", @"和", @"、", @"并使用本机号码登录"]
 */
@property (nullable, nonatomic, copy) NSArray<NSString *> *auxiliaryPrivacyWords;

/**
 * 点击授权页面隐私协议前勾选框的回调
 */
@property (nullable, nonatomic, copy) OLClickCheckboxBlock clickCheckboxBlock;

/**
* 服务条款文案对齐方式,默认为NSTextAlignmentLeft
*/
@property (nonatomic, assign) NSTextAlignment termsAlignment;

/**
 * 点击授权页面运营商隐私协议的回调
 */
@property (nullable, nonatomic, copy) OLViewPrivacyTermItemBlock carrierTermItemBlock;

/**
 * 是否在运营商协议名称上加书名号《》
 */
@property (nonatomic, assign) BOOL hasQuotationMarkOnCarrierProtocol;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置服务条款
// 隐私条款文字属性
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 1.33;
paragraphStyle.alignment = NSTextAlignmentLeft;
paragraphStyle.paragraphSpacing = 0.0;
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.firstLineHeadIndent = 0.0;
viewModel.privacyTermsAttributes = @{
                                     NSForegroundColorAttributeName : UIColor.orangeColor,
                                     NSParagraphStyleAttributeName : paragraphStyle,
                                     NSFontAttributeName : [UIFont systemFontOfSize:12]
                                     };
// 额外自定义服务条款,注意index属性,默认的index为0,SDK会根据index对多条服务条款升序排列,假如想设置服务条款顺序为 自定义服务条款1 默认服务条款 自定义服务条款2,则,只需将自定义服务条款1的index设为-1,自定义服务条款2的index设为1即可
KSCPrivacyTermItem *item1 = [[KSCPrivacyTermItem alloc] initWithTitle:@"自定义服务条款1"
                                                            linkURL:[NSURL URLWithString:@"https://docs.ksyun.com/documents/37157"]
                                                              index:0
                                                              block:^(KSCPrivacyTermItem * _Nonnull termItem, UIViewController *controller) {
                                                                   NSLog(@"termItem.termLink: %@, controller: %@", termItem.termLink, controller);
                                                                   // 自定义操作,可进入自定义服务条款页面                                                                  
                                                              }];
KSCPrivacyTermItem *item2 = [[KSCPrivacyTermItem alloc] initWithTitle:@"自定义服务条款2"
                                                            linkURL:[NSURL URLWithString:@"https://docs.ksyun.com/"]
                                                              index:0];
// 加载本地的html
NSURL *URL = [[NSBundle mainBundle] URLForResource:@"index.html" withExtension:nil];
NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
KSCPrivacyTermItem *item3 = [[KSCPrivacyTermItem alloc] initWithTitle:@"自定义服务条款3"
                                                         urlRequest:URLRequest
                                                              index:0
                                                              block:nil];
viewModel.additionalPrivacyTerms = @[item1, item2, item3];
KOLRect termsRect = {0, 0, 0, 0, 0, 0, {0, 0}};  // 服务条款偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.termsRect = termsRect;
viewModel.auxiliaryPrivacyWords = @[@"条款前文案", @"&", @"&", @"条款后的文案"];   // 条款之外的文案,默认可不设置

viewModel.clickCheckboxBlock = ^(BOOL isChecked) {      // 点击隐私条款前勾选框回调
    NSLog(@"clickCheckboxBlock isChecked: %@", isChecked ? @"YES" : @"NO");
};

viewModel.termsAlignment = NSTextAlignmentCenter;

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置服务条款
let paragraphStyle = NSMutableParagraphStyle.init()
paragraphStyle.lineSpacing = 1.33
paragraphStyle.alignment = NSTextAlignment.left
paragraphStyle.paragraphSpacing = 0.0
paragraphStyle.lineBreakMode = NSLineBreakMode.byWordWrapping
paragraphStyle.firstLineHeadIndent = 0.0
viewModel.privacyTermsAttributes = [NSAttributedString.Key.foregroundColor : UIColor.orange, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 12), NSAttributedString.Key.paragraphStyle : paragraphStyle]

let item1 = KSCPrivacyTermItem.init(title: "自定义服务条款1", linkURL: URL.init(string: "https://docs.ksyun.com/onelogin/overview/start")!, index: 0) { (termItem: OLPrivacyTeKSCPrivacyTermItemmItem, controller: UIViewController) in
    print("termItem.termLink: %@, controller: %@", termItem.termLink, controller)
}
let item2 = KSCPrivacyTermItem.init(title: "自定义服务条款2", linkURL: URL.init(string: "https://docs.ksyun.com/")!, index: 0)
// 加载本地的html
let url = Bundle.main.url(forResource: "index.html", withExtension: nil, subdirectory: nil)
let item3 = KSCPrivacyTermItem.init(title: "自定义服务条款2", linkURL: url!, index: 0)
viewModel.additionalPrivacyTerms = [item1, item2, item3]
let termsRect = KOLRect(portraitTopYOffset: 0, portraitCenterXOffset: 0, portraitLeftXOffset: 0, landscapeTopYOffset: 0, landscapeCenterXOffset: 0, landscapeLeftXOffset: 0, size: CGSize(width: 0, height: 0))  // 服务条款偏移、大小设置,偏移量和大小设置值需大于0,否则取默认值,默认可不设置
viewModel.termsRect = termsRect
viewModel.auxiliaryPrivacyWords = ["条款前文案", "&", "&", "条款后的文案"]   // 条款之外的文案,默认可不设置

viewModel.clickCheckboxBlock = { (isChecked) in      // 点击隐私条款前勾选框回调
    print("clickCheckboxBlock isChecked: %@", isChecked ? "true" : "false")
}

viewModel.termsAlignment = NSTextAlignment.center

9、设置授权页面弹出模式

授权页面弹出模式与 iOS UIViewController 的弹出模式保持一致,支持两种方式弹出授权页面,默认以模态方式弹出授权页面

/**
 * @abstract 进入授权页面的方式,默认为 modal 方式,即 present 到授权页面,从授权页面进入服务条款页面的方式与此保持一致
 * 
 * @discussion push 模式时,不支持弹窗模式,进入授权页面时,会隐藏导航栏,退出授权页面时,会显示导航栏,如果您进入授权页面的当前页面导航栏为隐藏状态,在授权页面消失时,请注意将导航栏隐藏
 */
typedef NS_ENUM(NSInteger, KSCOLPullAuthVCStyle) {
    KSCOLPullAuthVCStyleModal,
    KSCOLPullAuthVCStylePush
};

#pragma mark - KSCOLPullAuthVCStyle

/**
 * @abstract 进入授权页面的方式,默认为 modal 方式,即 present 到授权页面,从授权页面进入服务条款页面的方式与此保持一致
 */
@property (nonatomic, assign) KSCOLPullAuthVCStyle pullAuthVCStyle;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置 pullAuthVCStyle
viewModel.pullAuthVCStyle = KSCOLPullAuthVCStylePush; // 默认为 modal

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置 pullAuthVCStyle
viewModel.pullAuthVCStyle = KSCOLPullAuthVCStyle.push // 默认为 modal

10、设置状态栏

授权页面状态栏已默认适配黑夜模式,若您使用 SDK 默认的授权页面,可以无需设置状态栏,若您需要改变授权页面的背景,请您根据实际情况设置状态栏

/**
 状态栏样式。 默认 `UIStatusBarStyleDefault`。
 */
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;

示例代码

ObjC:

  1. 导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置状态栏
olAuthViewModel.statusBarStyle = UIStatusBarStyleDefault;

Swift:

  1. 创建混编桥接头文件并导入金山云 SDK 头文件 #import <KSCOneLoginSDK/KSCOneLoginSDK.h>
  2. 设置状态栏
viewModel.statusBarStyle = .lightContent

金山云,开启您的云计算之旅

免费注册