设置根控制器

控制器:

-主视图控制器(TabBarViewController)
-访客视图控制器(UITableViewController)
-欢迎视图控制器(UIViewController)
-OAthen授权视图控制器(UIViewController)
-子视图控制器(UITableViewController)

逻辑关系:

未登录状态下打开App--->访客视图
访客视图点击登录按钮-->OAthen授权界面
OAthen授权后-->欢迎视图控制器(dismiss OAthen控制器时发布通知,切换根控制器)
欢迎视图控制器结束-->主控制器(动画结束后欢迎视图控制器再次发布通知,切换根控制器)

主控制器下的子控制器继承自访客视图控制器,访客视图控制器通过是否登录标识判断显示登录或未登录视图界面

AppDelegate中代码示例:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        //设置主题颜色
        setThemeColor()
        //设置window
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        //设置背景色
        window?.backgroundColor = UIColor.whiteColor()
        //设置根控制器
        setupRootViewController()
        //设置主窗口并显示
        window?.makeKeyAndVisible()
        
        //监听通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(changeRootViewController(_:)), name: "changeTootViewControllerNotification", object: nil)
        
        return true
    }
    //设置根控制器
    func setupRootViewController() -> Void {
        
        if JSUserAccountTools.sharedTools.isLogin {
            //如果用户已登录,根控制器是欢迎界面
            window?.rootViewController = JSWelcomeViewController()
        }else {
            //如果用户未登录,根控制器是访客界面
            window?.rootViewController = JSTabBarController()
        }
        
    }
    //切换根控制器
    func changeRootViewController(notic: NSNotification) -> Void {
        
        if notic.object == nil {
            
            window?.rootViewController = JSWelcomeViewController()
        }else {
            
            window?.rootViewController = JSTabBarController()
        }
    }
    
    private func setThemeColor() -> Void{
        
        UITabBar.appearance().tintColor = THEMECOLOR
        UINavigationBar.appearance().tintColor = THEMECOLOR
    }
    
    deinit{
        //移除监听对象
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

欢迎视图控制器代码:

import UIKit
import SDWebImage

class JSWelcomeViewController: UIViewController {

    private lazy var backgroundImageView: UIImageView = UIImageView(imgName: "ad_background")
    
    private lazy var headImageView: UIImageView = {
        let img = UIImageView()
        img.layer.cornerRadius = 45
        img.layer.borderColor = THEMECOLOR.CGColor
        img.layer.borderWidth = 3
        img.clipsToBounds = true
        img.sd_setImageWithURL(NSURL(string: JSUserAccountTools.sharedTools.userAccount?.avatar_large ?? ""), placeholderImage: UIImage(named: "avatar_default_big"))
        return img
    }()
    
    private lazy var messageLabel: UILabel = {
        let lab = UILabel()
        lab.alpha = 0.01
        lab.text = "欢迎回来"
        lab.font = UIFont.systemFontOfSize(18)
        lab.textColor = UIColor.grayColor()
        lab.textAlignment = NSTextAlignment.Center
        return lab
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUI()
        
    }
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        
        self.headImageView.snp_updateConstraints { (make) in
            make.top.equalTo(self.view).offset(100)
        }
        
        //更改头像的约束(动画)
        UIView.animateWithDuration(2.5, delay: 1.5, usingSpringWithDamping: 0.7, initialSpringVelocity: 0, options: [], animations: {
            
            self.view.layoutIfNeeded()
            
            }) { (finished) in
                
                UIView.animateWithDuration(0.25, animations: { 
                    self.messageLabel.alpha = 1
                    
                    
                    }, completion: { (finished) in
                        
                        //切换根控制器
                    NSNotificationCenter.defaultCenter().postNotificationName("changeTootViewControllerNotification", object:"welcome")
                })
        }
        
        
    }
    
    //设置视图
    private func setUI() -> Void {
        
        //添加控件
        view.addSubview(headImageView)
        view.addSubview(messageLabel)
        
        //设置约束
        headImageView.snp_makeConstraints { (make) in
            
            make.top.equalTo(view).offset(400)
            make.centerX.equalTo(view)
            make.size.equalTo(CGSizeMake(90, 90))
        }
        
        messageLabel.snp_makeConstraints { (make) in
            
            make.top.equalTo(headImageView.snp_bottom).offset(16)
            make.centerX.equalTo(view)
        }
        
    }
    
    override func loadView() {
        view = backgroundImageView
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
 

}

OAthen视图控制器代码:

import UIKit
import SVProgressHUD
import AFNetworking

class JSOAuthViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //设置导航栏按钮
        setupNav()
        
        
    }
    
    // MARK: - 设置导航栏按钮
    private func setupNav ()->() {
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "取消", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(JSOAuthViewController.cancelClick))
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "自动填充", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(JSOAuthViewController.autoFillClick))
    }
    
    //左侧导航按钮点击事件
    @objc private func cancelClick() -> Void {
        dismissViewControllerAnimated(true, completion: nil)
    }
    //右侧导航按钮点击事件
    @objc private func autoFillClick ()->() {
        
        let jsString = "document.getElementById('userId').value='授权账户',document.getElementById('passwd').value='密码'"
        webView.stringByEvaluatingJavaScriptFromString(jsString)
        
    }
    
    override func loadView() {
        view = webView
        view.backgroundColor = UIColor.whiteColor()
        
        
    }
    
    // MARK: - 懒加载控件
    private lazy var webView: UIWebView = {
        
        let view = UIWebView()
        let url = NSURL(string: "https://api.weibo.com/oauth2/authorize?client_id=\(APPKEY)&redirect_uri=\(REDIRECT_URI)")!
        let request = NSURLRequest(URL: url)
        view.loadRequest(request)
        view.delegate = self;
        return view
        
    }()
    
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

}

extension JSOAuthViewController : UIWebViewDelegate{
    
    //开始加载
    func webViewDidStartLoad(webView: UIWebView) {
        
        SVProgressHUD.show()
    }
    //加载完成
    func webViewDidFinishLoad(webView: UIWebView) {
        SVProgressHUD.dismiss()
    }
    //加载失败
    func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
        
    }
    //将要加载request
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        
        let urlString = request.URL?.absoluteString
        
        if let u = urlString where u.hasPrefix(REDIRECT_URI) {
            
            //请求参数键值对
            let query = request.URL?.query
            
            if let q = query {
                
                let codeString = q.substringFromIndex("code=".endIndex)
                //请求数据
                oauthLoadUser(codeString)
                return false
            }
        }
        
        return true
    }
    
}

extension JSOAuthViewController{
    
    private func oauthLoadUser(code: String) -> Void {
        
        //请求数据,获取access_token等信息
        JSNetworkTool.sharedNetworkTool.oauthLoadUserAccount(code, success: { (response) in
            
            guard let res = response as? [String: AnyObject] else {
                
                return
            }
            //字典转模型
            let userAccount = JSUserAccountModel(dict: res)
            
            //请求用户信息
            self.loadUserInfo(userAccount)
            
            
            }) { (error) in
                
                print(error)
        }
        
        
    }
    
    
    
    //请求用户信息
    func loadUserInfo(userAccount: JSUserAccountModel) -> Void {
        
        JSNetworkTool.sharedNetworkTool.loadUserInfo(userAccount, success: { (response) in
            
            //判断是否有值,而且可以转成字典
            guard let res = response as? [String: AnyObject] else {
                
                return
            }
            userAccount.setValue(res["avatar_large"], forKey: "avatar_large")
            userAccount.setValue(res["screen_name"], forKey: "screen_name")
//            userAccount.avatar_large = res["avatar_large"] as? String
//            userAccount.screen_name = res["screen_name"] as? String
            
            JSUserAccountTools.sharedTools.saveUserAccount(userAccount: userAccount)
            //将OAuth控制器移除
            self.dismissViewControllerAnimated(false, completion: {
                //关闭指示器
                SVProgressHUD.dismiss()
                //切换根控制器
                NSNotificationCenter.defaultCenter().postNotificationName("changeTootViewControllerNotification", object: nil)
            })
            
            }) { (error) in
                
                print(error)
        }
        
    }
    
}

访客视图控制器:

class JSVistorTableViewController: UITableViewController {
    
    //标识用户是否登录
    let isLogin: Bool = JSUserAccountTools.sharedTools.isLogin
    
    //VistorView
    var vistorView: JSVistorView?
    
    override func loadView() {
        
        if isLogin {
            //已登录
            super.loadView()
            
        }else{
            //未登录
            setupVistorView()
        }
    }
    
    
    // MARK: - 设置导航栏
    private func setupNav()-> Void{
        
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "登录", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(loginClick))
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "注册", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(loginClick))
    }

    // MARK: - 导航栏按钮点击事件
    @objc private func loginClick() -> Void {
        
        let oauthVc = JSOAuthViewController()
        let naVC = JSNavigationController(rootViewController: oauthVc)
        presentViewController(naVC, animated: true, completion: nil)
        
    }
    
    // MARK: - 设置访客视图
    private func setupVistorView() -> Void {
        
        vistorView = JSVistorView()
        view = vistorView
        vistorView?.closure = {[weak self] in
            
            self?.loginClick()
        }
        
        //设置导航栏按钮
        setupNav()
    }
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }

    
}

将访客视图UI搭建抽取为单独一个类,并提供对外修改UI的方法

// MARK: - 供外界调用的方法,修改视图信息
    func setupVistorViewInfo(imgName: String?,title: String?) -> Void {
        
        if  let img = imgName,let tit = title {
            //非主页
            centerImageView.image = UIImage(named: img)
            messageLabel.text = tit
            feedImageView.removeFromSuperview()
            
        }else{
            
            //主页:设置动画
            setupAnim()
        }
        
    }

将OAthen授权获得的数据,存放到一个单例类中,同时做本地化处理,并存放是否登录的标识,防止每一次使用信息都对沙盒进行操作

class JSUserAccountTools: NSObject {
    
    //全局访问点
    static let sharedTools: JSUserAccountTools = JSUserAccountTools()
    
    var userAccount: JSUserAccountModel?
    
    var accessToken: String?{
        
        if userAccount?.access_token == nil {
            //如果访问令牌为nil,代表未登录,返回nil
            return nil
            
        }else {
            
            if userAccount?.expires_Date?.compare(NSDate()) == NSComparisonResult.OrderedDescending {
                //访问令牌不为nil,与当前时间比较为降序,未过期,代表登录
                return userAccount?.access_token
                
            }else {
                //如果访问令牌不为nil,但是时间过期,代表未登录
                return nil
            }
            
            
        }
    }
    
    //判断用户是否登录标识
    var isLogin: Bool {
        //如果access_token为nil,代表没登录(如果accessToken为nil,代表isLogin = false)
        return accessToken != nil
    }
    
    override init() {
        super.init()
        userAccount = getUserAccount()
    }
    
    let path = (NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! as NSString).stringByAppendingPathComponent("userAccount.archiver")
    
    
    //保存对象
    func saveUserAccount(userAccount userAcc: JSUserAccountModel) -> Void {
        
        self.userAccount = userAcc
        //归档
        NSKeyedArchiver.archiveRootObject(userAcc, toFile: path)
        
    }
    //获取对象
    func getUserAccount() -> JSUserAccountModel? {
        //解档
        let userAccount = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? JSUserAccountModel
        return userAccount
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容