Swift学习--微博的基础框架搭建
学习如何使用Swift写项目
一.搭建微博项目的主框架
1.1--搭建功能模块
1.2--在 AppDelegate
中的 didFinishLaunchingWithOptions
函数,设置启动控制器
import UIKit import CoreData @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. //创建Window window = UIWindow(frame: UIScreen.mainScreen().bounds) window?.backgroundColor = UIColor.whiteColor() //创建跟控制器 window?.rootViewController = MainViewController() window?.makeKeyWindow() return true } }
1.3--在MainViewController.swift中添加子控制器
override func viewDidLoad() { super.viewDidLoad() //设置当前控制器对应的tabbar的颜色 //注意:在ios7以前如果设置了tintColor志勇文字会变,但图片不会变 tabBar.tintColor = UIColor.orangeColor() addChildViewController(HomeTableViewController(), title: "首页", imageName: "tabbar_home") addChildViewController(HomeTableViewController(), title: "消息", imageName: "tabbar_message_center") addChildViewController(HomeTableViewController(), title: "广场", imageName: "tabbar_discover") addChildViewController(HomeTableViewController(), title: "我", imageName: "tabbar_profile") } /** 初始化子控制器 - parameter childController: 需要初始化的子控制器 - parameter title: 子控制器的标题 - parameter imageName: 子控制器的图片名字 */ private func addChildViewController(childController: UIViewController, title:String, imageName:String) { //设置控制器tabar对应的数据 childController.tabBarItem.image = UIImage(named: imageName) childController.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted") childController.title = title //2.给控制器包装一个导航栏控制器 let nav = UINavigationController() nav.addChildViewController(childController) //3.将导航栏控制器添加到当前控制器上 addChildViewController(nav) }
二.如何动态的创建控制器,在需求中可能遇到---在节假日中修改标签栏按钮的图标,这时就需要动态的创建控制器
2.1在项目中创建一个Json类MainVCSettings.json
[ { "vcName": "HomeTableViewController", "title": "首页", "imageName": "tabbar_home" }, { "vcName": "MessageTableViewController", "title": "消息", "imageName": "tabbar_message_center" }, { "vcName": "DiscoverTableViewController", "title": "广场", "imageName": "tabbar_discover" }, { "vcName": "ProfileTableViewController", "title": "我", "imageName": "tabbar_profile" } ]
2.1 具体实现代码
override func viewDidLoad() { super.viewDidLoad() //设置当前控制器对应的tabbar的颜色 //注意:在ios7以前如果设置了tintColor志勇文字会变,但图片不会变 tabBar.tintColor = UIColor.orangeColor() //1.获取json文件的路径 let path = NSBundle.mainBundle().pathForResource("MainVCSettings.json", ofType: nil) //2.通过文件路径创建NSData if let jsonPath = path{ let jsonData = NSData(contentsOfFile: jsonPath) do{ //可能发生的异常代码放到这里 //序列话json数据->Array //Try:发生异常会跳到catch中继续执行 //Try! :发生一次程序直接崩溃 let dictArr = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers) //遍历数组,动态创建控制器和设置数据 //在Swift中,如果需要遍历一个数组,必须明确数据的类型 for dict in dictArr as! [[String: String]] { //报错的原因是因为addChildViewController参数必须有值,但是字典的返回值是可选类型 addChildViewController(dict["vcName"]!, title: dict["title"]!, imageName: dict["imageName"]!) } } catch { //发生异常之后会执行的代码 print(error) //从本地创建控制器 addChildViewController("HomeTableViewController", title: "首页", imageName: "tabbar_home") addChildViewController("MessageTableViewController", title: "消息", imageName: "tabbar_message_center") addChildViewController("DiscoverTableViewController", title: "广场", imageName: "tabbar_discover") addChildViewController("ProfileTableViewController", title: "我", imageName: "tabbar_profile") } } } /** 初始化子控制器 - parameter childController: 需要初始化的子控制器 - parameter title: 子控制器的标题 - parameter imageName: 子控制器的图片名字 */ private func addChildViewController(childControllerName: String, title:String, imageName:String) { //动态获取命名空间 let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String //1.将字符串转换为类 //默认情况下命名空间就是项目的名称,但是命名空间名称是可以修改的 let cls:AnyClass? = NSClassFromString(ns + "." + childControllerName) //2通过类创建对象 //将AnyClass转换为指定的类型 let vcCls = cls as! UIViewController.Type //通过class创建对象 let vc = vcCls.init() //设置控制器tabar对应的数据 vc.tabBarItem.image = UIImage(named: imageName) vc.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted") vc.title = title //2.给控制器包装一个导航栏控制器 let nav = UINavigationController() nav.addChildViewController(vc) //3.将导航栏控制器添加到当前控制器上 addChildViewController(nav) }
三.创建微博中间加号按钮
override func viewDidLoad() { super.viewDidLoad() //设置当前控制器对应的tabbar的颜色 //注意:在ios7以前如果设置了tintColor志勇文字会变,但图片不会变 tabBar.tintColor = UIColor.orangeColor() //添加子控制器 addChildViewControllers() } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) // 此时 tabBarButton 都已经创建 print(tabBar.subviews) // 初始化加号按钮 setupComposeBtn() } //添加子控制器 func addChildViewControllers(){ //1.获取json文件的路径 let path = NSBundle.mainBundle().pathForResource("MainVCSettings.json", ofType: nil) //2.通过文件路径创建NSData if let jsonPath = path{ let jsonData = NSData(contentsOfFile: jsonPath) do{ //可能发生的异常代码放到这里 //序列话json数据->Array //Try:发生异常会跳到catch中继续执行 //Try! :发生一次程序直接崩溃 let dictArr = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers) //遍历数组,动态创建控制器和设置数据 //在Swift中,如果需要遍历一个数组,必须明确数据的类型 for dict in dictArr as! [[String: String]] { //报错的原因是因为addChildViewController参数必须有值,但是字典的返回值是可选类型 addChildViewController(dict["vcName"]!, title: dict["title"]!, imageName: dict["imageName"]!) } } catch { //发生异常之后会执行的代码 print(error) //从本地创建控制器 addChildViewController("HomeTableViewController", title: "首页", imageName: "tabbar_home") addChildViewController("MessageTableViewController", title: "消息", imageName: "tabbar_message_center") // 添加占位控制器 addChildViewController("PlusViewController", title: "", imageName: "") addChildViewController("DiscoverTableViewController", title: "广场", imageName: "tabbar_discover") addChildViewController("ProfileTableViewController", title: "我", imageName: "tabbar_profile") } } } private lazy var composeBtn:UIButton = { // 1.创建按钮 let button = UIButton() // 2.设置图片 button.setImage(UIImage(named: "tabbar_compose_icon_add"), forState: UIControlState.Normal) button.setImage(UIImage(named: "tabbar_compose_icon_add_highlighted"), forState: UIControlState.Highlighted) // 3.设置背景图片 button.setBackgroundImage(UIImage(named: "tabbar_compose_button"), forState: UIControlState.Normal) button.setBackgroundImage(UIImage(named: "tabbar_compose_button_highlighted"), forState: UIControlState.Highlighted) // 4.添加监听 button.addTarget(self, action: "composetBtnClick", forControlEvents: UIControlEvents.TouchUpInside) // 5.添加到tabBar上 // Swift中能不写self就不写self, 在闭包中必须写self // self.tabBar.addSubview(button) // 6.返回按钮 return button }() // 运行循环监听到事件后,向 VC 发送消息,动态执行 方法,因此不能设置为 private func composetBtnClick() { print(__FUNCTION__) } /** 初始化子控制器 - parameter childController: 需要初始化的子控制器 - parameter title: 子控制器的标题 - parameter imageName: 子控制器的图片名字 */ private func addChildViewController(childControllerName: String, title:String, imageName:String) { //动态获取命名空间 let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String //1.将字符串转换为类 //默认情况下命名空间就是项目的名称,但是命名空间名称是可以修改的 let cls:AnyClass? = NSClassFromString(ns + "." + childControllerName) //2通过类创建对象 //将AnyClass转换为指定的类型 let vcCls = cls as! UIViewController.Type //通过class创建对象 let vc = vcCls.init() //设置控制器tabar对应的数据 vc.tabBarItem.image = UIImage(named: imageName) vc.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted") vc.title = title //2.给控制器包装一个导航栏控制器 let nav = UINavigationController() nav.addChildViewController(vc) //3.将导航栏控制器添加到当前控制器上 addChildViewController(nav) } /** 设置加号按钮位置 */ private func setupComposeBtn(){ // 0.添加到tabBar上 tabBar.addSubview(composeBtn) // 1.计算按钮宽度 let width = tabBar.bounds.width / CGFloat(viewControllers!.count) // 2.创建按钮frame let rect = CGRect(x: 0, y: 0, width: width, height: tabBar.bounds.height) // 3.设置按钮frame和偏移位 composeBtn.frame = CGRectOffset(rect, width * 2, 0) }