swift项目第四天:动态加载控制器

   2023-02-09 学习力0
核心提示:一:Appdelegateimport UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {/* 总结: 1:1:window为可选类型,可选类型的定义:var window: UIWindow?,可选类型就是可以为空值nil或是有值,若是想获得可选类型的值,则可以进

一:Appdelegate

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    /*
     总结:
     1:1:window为可选类型,可选类型的定义:var window: UIWindow?,可选类型就是可以为空值nil或是有值,若是想获得可选类型的值,则可以进行可选绑定或是强制解包,若是强制解包必须要保证强制解包的值不为nil,若为nil会产生崩溃,一般可选绑定用guard else进行校验(let会自动解包) 2:var window: UIWindow?,为该类的属性,定义属性的时候,必须保证属性有初始化值,或是定义成可选类型,否则会报错
     2:需要自己去创建window:创建对象就用构造函数:RHTabBarViewController(),获得实例对象之后,调用方法可以使用点语法window?.makeKeyAndVisible()
     window = UIWindow(frame:UIScreen.main.bounds)
     window?.rootViewController = RHTabBarViewController()
     window?.makeKeyAndVisible()
     
     3:设置全局tabBar的样式:设置tabBar的tintColor,就是改变tabbarItem的图片文字颜色,若不设置,则系统会自动将图片和文字渲染为蓝色:UITabBar.appearance().tintColor = UIColor.orange
     4:设置全局的函数,或是全局的样式,都在AppDelegate文件中去设置
     
     */
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        
        //MARK:-1:创建window
        window = UIWindow(frame:UIScreen.main.bounds)
        window?.rootViewController = RHTabBarViewController()
        window?.makeKeyAndVisible()
        
        //MARK:-2:设置全局tabbar的样式
        UITabBar.appearance().tintColor = UIColor.orange
        
        DLog(message: "123")
        
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }
    
    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    
    
}

//MARK:-3:定义全局的DLog:使用全局函数:传默认参数
/*
 总结:1:设置全局函数都在AppDelegate中进行设置,class 类声明之后
 
 2: 自定义Log: 定义Log 1. 定义Log的打印内容
 获取所在的文件 #FILE 获取所在的方法 #FUNCTION 获取所在的行 #LINE
 默认参数:当在方法中传参数时,也可以传入默认参数,定义:file : String = #file,默认参数在外界传递参数的时候不会显示
 全局函数:在AppDelegate中定义全局函数:<T>表示泛型,传打印内容:func DLog<T> (message: T,fileName:String = #file,funcName:String = #function,lineNum:Int = #line) 2.DLog在Debug下 打印,在release下 不打印
 定义标记项 —>buildSettings—>搜索swift flag—>Debug -> -D DEBUG 做标记--------在项目中实现:#if DEBUG    #endif
 
 3:1:#if DEBUG  //DEBUG模式下
 
 let file = (fileName as NSString).lastPathComponent;
 
 print("\(file):\(funcName):\(lineNum):\("打印内容"):\(message)")
 
 #endif
 
 2:let file = (fileName as NSString).lastPathComponent;获取文件的扩展名,(fileName as NSString)将swift的字符串转为OC字符串,并调用OC的方法,关键字as,在截取字符串的时候也通常将swift的字符串转为OC字符串来进行截取
 3: print("\(file):\(funcName):\(lineNum):\("打印内容"):\(message)"):插值运算:插值运算"\()"来表示。
 
 */



func DLog<T> (message: T,fileName:String = #file,funcName:String = #function,lineNum:Int = #line) {
    
    #if DEBUG
        
        let file = (fileName as NSString).lastPathComponent;
        
        print("\(file):\(funcName):\(lineNum):\("打印内容"):\(message)")
        
    #endif
    
}

二:RHTabBarViewController

import UIKit

class RHTabBarViewController: UITabBarController {

    /**
     
     总结:1:1:在RHTabBarViewController上添加子控制器:需要封装一个函数(封装的函数写在class类里),外部传控制器对象,title,imageName 2:swift支持方法的重载,方法的重载:方法名称相同,但是参数不同. --> 1.参数的类型不同 2.参数的个数不同,在定义函数时使用private修饰,表示在当前文件中可以访问,但是其他文件不能访问private func addChildViewController(_ childController: UIViewController,title : String,imageName:String),其中第一个参数的下划线可以省略,那么如果省略外部调用,第一个参数名就会显示出来,  addChildViewController(childController: <#T##UIViewController#>, title: <#T##String#>, imageName: <#T##String#>)
         如果不省略: addChildViewController(<#T##childController: UIViewController##UIViewController#>, title: <#T##String#>, imageName: <#T##String#>)
     
         2:创建对象用的是构造函数:RHHomeTableViewController(),在封装的方法中,设置tabBar的标题,图片:childController.title, childController.tabBarItem.image, childController.tabBarItem.selectedImage
           其中:
            childController.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted"),字符串与字符串的拼接就用 + ,添加子控制器:addChildViewController(childNav),可以省略self去调用
     
     */
    
   
    override func viewDidLoad() {
        super.viewDidLoad()
        
         //MARK:-通过json文件创建初始化控制器
        
        //1:读取json文件的路径
        
        /*
         
        let urlPath = Bundle.main.path(forResource: "MainVCSettings.json", ofType: nil)//urlPath为可选类型
        
        guard (urlPath != nil) else {
            DLog(message: "获取文件路径失败")
            return
        }
 
        不能:swift中没有非0即真,不能时候如下写法,不许有明确的值,(urlPath != nil)
         
         guard urlPath else {
         DLog(message: "获取文件路径失败")
         return
         }
        */
        
        guard let urlPath = Bundle.main.path(forResource: "MainVCSettings.json", ofType: nil) else {
              DLog(message: "获取文件路径失败")
            return
        }
        
        guard let data = try? Data.init(contentsOf: URL(fileURLWithPath: urlPath)) else {
            DLog(message: "获取文件data失败")
              return
            
        }
        
        guard let infoArr = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) else {
            
            DLog(message: "获取文件infoDic失败")
            return
        }
        
        guard let dataArr = infoArr as? [[String : AnyObject]] else {
            
            DLog(message: "获取文件dataArr失败")
            return
        }
        
        /*
         1:从数组或是字典中取出的数据都是AnyObject类型,需要将AnyObject类型转为可选类型,用as?来进行转换,转成为string类型的可选类型
         
         2:一般可选类型都与guard else进行校验,as?,将其他类型转为可选类型
         */
        for  dic in dataArr {
            
            guard let vcName = dic["vcName"] as? String else {
                
                continue
            }
            
            guard let title = dic["title"] as? String else {
                
                continue
            }
            
            guard let iamgeName = dic["imageName"] as? String else {
                
                continue
            }
            
        addSubChildViewController(className: vcName, title: title, imageName: iamgeName)
        
            
        }
        
     
//         //MARK:-1:添加子控制器
//    
//        //首页
//        addChildViewController(RHHomeTableViewController(), title: "首页", imageName: "tabbar_home")
//        
//        //信息
//        addChildViewController(RHMessageTableViewController(), title: "信息", imageName: "tabbar_message_center")
//        
//        //发现
//        addChildViewController(RHDiscoverViewController(), title: "发现", imageName: "tabbar_discover")
//        
//        ////        addChildViewController(RHProfileTableViewController(), title: "我", imageName: "tabbar_profile")
        
  
    }

    //MARK:-1:添加子控制器:private:私有方法,

    private func addChildViewController(_ childController: UIViewController,title : String,imageName:String) {
        
        //1:设置子控制器tabBarItem的标题图片
        childController.title = title;
        childController.tabBarItem.image = UIImage(named: imageName)
        childController.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted")
        
        //2:添加子控制器
        let childNav = UINavigationController(rootViewController: childController)
        addChildViewController(childNav)
        
    }
    
    private func addSubChildViewController(className:String,title:String,imageName:String) {
        
        
        /*
        
         1: let nameSpace = Bundle.main.infoDictionary,此时的nameSpace为一个可选类型的字典,而我们能确定此可选类型的info.plist文件中肯定有值所以可以强制解包,Bundle.main.infoDictionary!["CFBundleExecutable"],此时强制解包出来的nameSpace为Any的类型,需要将Any转换为String?的可选类型用as?来进行转换
         
         2:从数组或是字典取出来的数据为都为Any?的可选类型,1:如果一定有值的话,直接!进行强制解包,变为Any类型,还需要将Any类型的nameSpace转换为string?类型的可选类型,用as?来进行转换 2:如果不确定一定有值的话,可以用1:可选绑定 2:用guard else 进行校验
         3: guard 校验两种写法:1:
         
         let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String;
         
         guard (nameSpace != nil) else {
         
            return
         }
         2:
         
         guard   let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else {
         
         return
         }
         
         */
      
        ///1:获取命名空间
//        let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String;
        
        /*
         此句代码没有进行解包,只是判断可选类型是否为nil
         */
        guard  let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else {
            return
        }
        
        
        ///2:获取类名
        
        /*
         1:获取的类名,classfullName的类型为AnyClass?类型
         
           let classfullName = NSClassFromString(nameSpace! + "." + className)
         2:直接用guard else进行校验,当用 let classfullName = NSClassFromString(nameSpace! + "." + className)此种类型为可选绑定,有值的话,直接将可选类型进行解包
         3:如果 guard (nameSpace != nil) else {
             return
         }
         此种写法,不会对nameSpace进行解包
        
         */
      

        ///3:创建对象
        guard let classfullName = NSClassFromString(nameSpace + "." + className) else {
        
            return
        }
        
        guard let childVC = classfullName as? UIViewController.Type else {
            
            return
        }
        
        let childVCtroller = childVC.init();
        
        childVCtroller.title = title
        childVCtroller.tabBarItem.image = UIImage(named: imageName)
        childVCtroller.tabBarItem.selectedImage = UIImage(named: imageName + "_highlighted")
        
        let childNav = UINavigationController(rootViewController: childVCtroller)
        
        addChildViewController(childNav)
        
        
    }
        
    
        
       
}

三:异常处理

import UIKit
/**
 总结:1:当调用某个函数有throw标志的时候,是表示该函数会抛出异常,swift抛出异常的方式有三种,try:都 catch 捕获异常,error有异常信息,try?:可选类型捕获异常,有异常会返回控制nil,try!:方式危险,若是有异常,直接会发生崩溃
 
      2:三种表达方式:1:try:do catch
 do {
 let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
 } catch {
 print(error)
 }
 
   2:try?:可选类型,用guard else去校验
 
 guard let regex = try? NSRegularExpression(pattern: pattern, options: .CaseInsensitive) else {
 return
 }
 
 3:try!:方式危险,若是有异常,直接会发生崩溃
 let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)

 
 */
class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 正则表达式
        // 1.创建正则表达式的规则
        let pattern = "abc"
        
        // 2.创建正则表达式对象
        
        // 方式一:try方式
//        do {
//          let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
//        } catch {
//            print(error)
//        }
        
        // 方式二:try?方式:
//        guard let regex = try? NSRegularExpression(pattern: pattern, options: .CaseInsensitive) else {
//            return
//        }
        
        
        // 方式三:try!方式(危险)
        let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    }
}

 

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • swift 命令行工具初探
    亲爱的同学们好,今天我们要介绍这么一个东西。相信有过解释型语言(PHP,Ruby,等)使用经验的同学会更加熟悉,就是 Swift 也为我们提供了命令行运行工具,俗称 REPL。好了,我们进入正题,在安装好 Swift 开发环境的机器上,打开命令行,输入 swift 命令,就进
    03-16
  • [Swift]冒泡排序 | Bubble sort
    [Swift]冒泡排序 | Bubble sort
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)➤GitHub地址:https://github.com/strengthen/LeetCode➤原文
    03-08
  • [Swift] 自定义在 SwiftUI 中实现的可搜索的外观
    [Swift] 自定义在 SwiftUI 中实现的可搜索的外
    首先我找遍了,似乎找不到任何信息......(我遇到了许多根本不起作用的事情......)终于在详细的英文文献中找到了,我会保留下来,希望以后有机会。关于 SwiftUI 中的可搜索searchable是iOS15新增的易于实现的搜索字段。关于这种情况有一个参数placement,您
    03-08
  • [Swift] 检测 SwiftUI ScrollView 中的偏移量
    [Swift] 检测 SwiftUI ScrollView 中的偏移量
    首先你可以用ScrollViewReader做一些可以从iOS14使用的事情。但是,我不能做我想做的事情,所以我想我还能做些什么。再次,可重复使用我尝试过了。执行我将首先发布实现的图像。 (Swift Playgrounds 演示)您可以像这样根据滚动获取坐标。让我们看看实现。1.
    03-08
  • Swift3.0 UICollectionView 删除,拖动
    Swift3.0 UICollectionView 删除,拖动
    UICollectionView实现了一下常见的新闻分类.  附有效果图 近期一直在深入学习swift,实现了CollectionView item的头东与删除,用的都是系统的一些函数方法,看起来比较直观. 第一步:class HotViewController: UIViewController,UICollectionViewDelegate,UICo
    02-09
  • swift -懒加载创建view
     // 只有外界访问到headerView的时候才会去执行闭包, 然后将闭包的返回值赋值给headerView    // 注意: 一定要记住闭包后面需要写上(), 代表执行闭包    //懒加载创建UIView    lazy var headerView: UIView = {        let view = UIView()
    02-09
  • Swift--非常好用的适合局部的代码约束
    // 哪个控件的哪个属性等于(大于、小于)另外一个控件的哪个属性乘以多少再加上多少 eg:let widthContraint = NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLa
    02-09
  • iOS打包framework - Swift完整项目打包Framework,嵌入OC项目使用
    iOS打包framework - Swift完整项目打包Framewor
    场景说明:-之前做的App,使用Swift框架语言,混合编程,内含少部分OC代码。-需要App整体功能打包成静态库,完整移植到另一个App使用,该App使用OC。-所以涉及到一个语言互转的处理,以及一些AppDelegate的代码减除变化。 --------------------------------
    02-09
  • Swift -- 官方文档Swift-Guides的学习笔记
    在经历的一段时间的郁闷之后,我发现感情都是虚伪的,只有代码是真实的(呸)因为看了swift语法之后依然不会用swift,然后我非常作死的跑去看官方文档,就是xcode里自带的help》documentation and API reference其中的swift里的guide这里主要总结一下里面每一
    02-09
  • Swift - 进度条(UIProgressView)的用法
     1,创建进度条1234var progressView=UIProgressView(progressViewStyle:UIProgressViewStyle.Default)progressView.center=self.view.centerprogressView.progress=0.5 //默认进度50%self.view.addSubview(progressView); 2,设置进度,同时有动画效果1p
    02-09
点击排行