控制器:
-主視圖控制器(TabBarViewController)
-訪客視圖控制器(UITableViewController)
-歡迎視圖控制器(UIViewController)
-OAthen授權(quán)視圖控制器(UIViewController)
-子視圖控制器(UITableViewController)
邏輯關(guān)系:
未登錄狀態(tài)下打開App--->訪客視圖
訪客視圖點(diǎn)擊登錄按鈕-->OAthen授權(quán)界面
OAthen授權(quán)后-->歡迎視圖控制器(dismiss OAthen控制器時(shí)發(fā)布通知,切換根控制器)
歡迎視圖控制器結(jié)束-->主控制器(動畫結(jié)束后歡迎視圖控制器再次發(fā)布通知,切換根控制器)
主控制器下的子控制器繼承自訪客視圖控制器,訪客視圖控制器通過是否登錄標(biāo)識判斷顯示登錄或未登錄視圖界面
AppDelegate中代碼示例:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//設(shè)置主題顏色
setThemeColor()
//設(shè)置window
window = UIWindow(frame: UIScreen.mainScreen().bounds)
//設(shè)置背景色
window?.backgroundColor = UIColor.whiteColor()
//設(shè)置根控制器
setupRootViewController()
//設(shè)置主窗口并顯示
window?.makeKeyAndVisible()
//監(jiān)聽通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(changeRootViewController(_:)), name: "changeTootViewControllerNotification", object: nil)
return true
}
//設(shè)置根控制器
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{
//移除監(jiān)聽對象
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")
})
}
}
//設(shè)置視圖
private func setUI() -> Void {
//添加控件
view.addSubview(headImageView)
view.addSubview(messageLabel)
//設(shè)置約束
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()
//設(shè)置導(dǎo)航欄按鈕
setupNav()
}
// MARK: - 設(shè)置導(dǎo)航欄按鈕
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))
}
//左側(cè)導(dǎo)航按鈕點(diǎn)擊事件
@objc private func cancelClick() -> Void {
dismissViewControllerAnimated(true, completion: nil)
}
//右側(cè)導(dǎo)航按鈕點(diǎn)擊事件
@objc private func autoFillClick ()->() {
let jsString = "document.getElementById('userId').value='授權(quán)賬戶',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) {
//請求參數(shù)鍵值對
let query = request.URL?.query
if let q = query {
let codeString = q.substringFromIndex("code=".endIndex)
//請求數(shù)據(jù)
oauthLoadUser(codeString)
return false
}
}
return true
}
}
extension JSOAuthViewController{
private func oauthLoadUser(code: String) -> Void {
//請求數(shù)據(jù),獲取access_token等信息
JSNetworkTool.sharedNetworkTool.oauthLoadUserAccount(code, success: { (response) in
guard let res = response as? [String: AnyObject] else {
return
}
//字典轉(zhuǎn)模型
let userAccount = JSUserAccountModel(dict: res)
//請求用戶信息
self.loadUserInfo(userAccount)
}) { (error) in
print(error)
}
}
//請求用戶信息
func loadUserInfo(userAccount: JSUserAccountModel) -> Void {
JSNetworkTool.sharedNetworkTool.loadUserInfo(userAccount, success: { (response) in
//判斷是否有值,而且可以轉(zhuǎn)成字典
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: {
//關(guān)閉指示器
SVProgressHUD.dismiss()
//切換根控制器
NSNotificationCenter.defaultCenter().postNotificationName("changeTootViewControllerNotification", object: nil)
})
}) { (error) in
print(error)
}
}
}
訪客視圖控制器:
class JSVistorTableViewController: UITableViewController {
//標(biāo)識用戶是否登錄
let isLogin: Bool = JSUserAccountTools.sharedTools.isLogin
//VistorView
var vistorView: JSVistorView?
override func loadView() {
if isLogin {
//已登錄
super.loadView()
}else{
//未登錄
setupVistorView()
}
}
// MARK: - 設(shè)置導(dǎo)航欄
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: - 導(dǎo)航欄按鈕點(diǎn)擊事件
@objc private func loginClick() -> Void {
let oauthVc = JSOAuthViewController()
let naVC = JSNavigationController(rootViewController: oauthVc)
presentViewController(naVC, animated: true, completion: nil)
}
// MARK: - 設(shè)置訪客視圖
private func setupVistorView() -> Void {
vistorView = JSVistorView()
view = vistorView
vistorView?.closure = {[weak self] in
self?.loginClick()
}
//設(shè)置導(dǎo)航欄按鈕
setupNav()
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
將訪客視圖UI搭建抽取為單獨(dú)一個(gè)類,并提供對外修改UI的方法
// MARK: - 供外界調(diào)用的方法,修改視圖信息
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{
//主頁:設(shè)置動畫
setupAnim()
}
}
將OAthen授權(quán)獲得的數(shù)據(jù),存放到一個(gè)單例類中,同時(shí)做本地化處理,并存放是否登錄的標(biāo)識,防止每一次使用信息都對沙盒進(jìn)行操作
class JSUserAccountTools: NSObject {
//全局訪問點(diǎn)
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,與當(dāng)前時(shí)間比較為降序,未過期,代表登錄
return userAccount?.access_token
}else {
//如果訪問令牌不為nil,但是時(shí)間過期,代表未登錄
return nil
}
}
}
//判斷用戶是否登錄標(biāo)識
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
}
}