美文网首页
Swift 学习整理

Swift 学习整理

作者: 学无止境666 | 来源:发表于2020-04-08 23:42 被阅读0次

    1: 实现自定义UITabBarController

    效果图如下


    截屏2020-04-0823.21.10.png

    创建一个继承于UITabBarController的子类
    代码如下

    class MainTabBarController: UITabBarController {
    
        open var titleArray = NSMutableArray.init(objects: "首页", "第二页", "第三页", "第四页", "我的")
        override func viewDidLoad() {
            super.viewDidLoad()
    
            addTabBarChildViewControl(childVC: ViewController(), title: titleArray.object(at: 0) as! NSString, imageName: "TabMenu_Home_Normal", selectImageName: "TabMenu_Home_Highlight", index: 0)
            
            addTabBarChildViewControl(childVC: SecondViewController(), title:titleArray.object(at: 1) as! NSString, imageName: "TabMenu_Finacing_Normal", selectImageName: "TabMenu_Finacing_Highlight", index: 1)
    
            addTabBarChildViewControl(childVC: ThirdViewController(), title: titleArray.object(at: 2) as! NSString, imageName: "TabMenu_MyStock_Normal", selectImageName: "TabMenu_MyStock_Highlight", index: 2)
            
            addTabBarChildViewControl(childVC: FourthViewController(), title: titleArray.object(at: 3) as! NSString, imageName: "TabMenu_Trade_Normal", selectImageName: "TabMenu_Trade_Highlight", index: 3)
            
            addTabBarChildViewControl(childVC: FifthViewController(), title: titleArray.object(at: 4) as! NSString, imageName: "TabMenu_Home_Normal", selectImageName: "TabMenu_Mine_Highlight", index: 4)
            //处理选中tabBar的字体颜色
            self.tabBar.tintColor = UIColor.red
        }
        
        //添加tabBarVC控制器
        private func addTabBarChildViewControl (childVC : UIViewController, title : NSString, imageName : NSString, selectImageName : NSString, index : Int) {
    
            //确保使用原图
            let tempSelectImage = UIImage(named:selectImageName as String)?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
            let vcItem = UITabBarItem.init(title: title as String, image: UIImage.init(named: (imageName as String)), selectedImage: tempSelectImage)
            vcItem.tag = index
            childVC.tabBarItem = vcItem
            //BaseNavigationController 继承于 UINavigationController 的子类 主要处理push二级页面hidesBottomBarWhenPushed的显示问题
            let navigationVC = BaseNavigationController.init(rootViewController: childVC)
            addChild(navigationVC)
        }
        //重写tabBar的选中事件,可以在这里处理一些事件,如埋点之类事件
        override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
            print("didSlectindex:\(item.tag)");
        }
    }
    

    2:统一处理二级页面的底部hidesBottomBarWhenPushed(bottomBar)的显示问题

    写一个继承于UINavigationController 的子类BaseNavigationController,在个类中统一处理push事件,代码如下

        //重写pushViewController方法判断子页面大于0就隐藏底部bottomBar
        override func pushViewController(_ viewController: UIViewController, animated: Bool) {
            if children.count > 0 {
                viewController.hidesBottomBarWhenPushed = true
            }
            super.pushViewController(viewController, animated: animated)
        }
    

    3 : 处理页面间push,pop跳转问题,及跳转指定根视图控制器

    // 跳转指定控制器
        func jumpDesignatedController() {
            
            // 方法一(跳转指定控制器)
            let mineVC = MyAcountAuthViewController()
            var targetVC : UIViewController!
            for controller in self.navigationController!.viewControllers {
                if controller.isKind(of: mineVC.classForCoder) {
                    targetVC = controller
                }
            }
            if targetVC != nil {
                self.navigationController?.popToViewController(targetVC, animated: true)
            }
            
            // 方法二(跳转根控制器)
            self.navigationController?.popToRootViewController(animated: true)
            
            // 方法三(返回到根界面的某个控制器)
            self.navigationController?.tabBarController?.hidesBottomBarWhenPushed = false
            self.navigationController?.tabBarController?.selectedIndex = 0 // (第一个控制器)
            self.navigationController?.popToRootViewController(animated: true)
            // 方法四(返回两级界面)
            if (self.navigationController?.viewControllers.count)! >= 2 {
                guard let vc = self.navigationController?.viewControllers[1] else { return }
                self.navigationController?.popToViewController(vc, animated: true)
            }
        }
    

    4 : Swift 使用WKWebView

    简单使用如下,后续可以创建一个基类出来,方便管理

    //引入框架
    import WebKit
    class FourthViewController: BaseViewController {
    
        var wkWebView : WKWebView?
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //初始化WKWebView
            self.wkWebView = WKWebView.init(frame: self.view.frame)
            //添加一个简单的html页面(百度)
            self.wkWebView?.load(URLRequest.init(url: NSURL.init(string: "https://www.baidu.com")! as URL))
            //加载本地html资源
    //        self.wkWebView.load(URLRequest.init(url: URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html")!)))
            
            self.view.addSubview(self.wkWebView!)
        }
    }
    

    5 自定义tableViewCell 并使用model对数据赋值

    • 自定义model
    class WFListInfoModel: NSObject {
        var titleName : String
        var subTitleName : String
        var leftImageName : String
        var rightBtnName : String
        
        init(titleName: String, subTitleName:String, leftImageName: String, rightBtnName: String) {
            self.titleName = titleName
            self.subTitleName = subTitleName
            self.leftImageName = leftImageName
            self.rightBtnName = rightBtnName
        }
    }
    
    • 自定义cell并赋值
    import UIKit
    
    class WFCommonCell: UITableViewCell {
        
        private var leftImageView : UIImageView?
        private var titleLabel : UILabel?
        private var subTitleLabel : UILabel?
        private var rightButton : UIButton?
        private var cellInfoModel : WFListInfoModel?
        
        open func leftImageName (imageName: String) {
            self.leftImageView?.image = UIImage.init(named: imageName)
        }
        //model 赋值
        open func cellInfoModel(infoModel: WFListInfoModel) {
            self.cellInfoModel = infoModel
            self.leftImageView?.image = UIImage.init(named: infoModel.leftImageName)
            self.titleLabel?.text = infoModel.titleName
            self.subTitleLabel?.text = infoModel.subTitleName
            self.rightButton?.setTitle(infoModel.rightBtnName, for: UIControl.State.normal)
        }
    
        
        override func awakeFromNib() {
            super.awakeFromNib()
            // Initialization code
        }
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            self.selectionStyle = UITableViewCell.SelectionStyle.none
            
            self.createUI()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        //创建UI
        func createUI (){
            var origin_X = 15 as Int
            self.leftImageView = WFCreateImageView(rect: CGRect.init(x: origin_X, y: 0, width: cellHeight, height: cellHeight), imageName: "TabMenu_Mine_Highlight")
            self.leftImageView?.layer.masksToBounds = true
            self.leftImageView?.layer.cornerRadius = CGFloat(cellHeight/2);
            origin_X += cellHeight
            
            self.titleLabel = WFCreateLabel(rect: CGRect.init(x: origin_X, y: 0, width: 100, height: cellHeight/2), title: "名称", titleColor: UIColor.black, alignment: NSTextAlignment.left, font: UIFont.systemFont(ofSize: 25))
            self.subTitleLabel = WFCreateLabel(rect: CGRect.init(x: origin_X, y: cellHeight/2, width: 100, height: cellHeight/2), title: "详情", titleColor: UIColor.lightGray, alignment: NSTextAlignment.left, font: UIFont.systemFont(ofSize: 15))
            origin_X += 100
    
            self.rightButton = WFCreateButton(target: self, rect: CGRect.init(x: Int(kMainScreenWidth - 15 - 80), y: 0, width: 80, height: cellHeight), title: "试试看", titleColor: UIColor.blue, selector: #selector(rightBtnAction), event: UIControl.Event.touchUpInside)
            
            self.contentView.addSubview(self.leftImageView!)
            self.contentView.addSubview(self.titleLabel!)
            self.contentView.addSubview(self.subTitleLabel!)
            self.contentView.addSubview(self.rightButton!)
    
        }
        
    //    override func prepareForInterfaceBuilder() {
    //
    //    }
        
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
    
            // Configure the view for the selected state
        }
        
        //不带返回值的闭包
        private let studname = {(title: String) -> () in
            print("title = \(title)")
        }
        
        //返回string类型的闭包
        private let appendName = {(name: String) -> (String) in
            return "\(name)_0"
        }
    
        
        @objc func rightBtnAction(rightBtn: UIButton) {
        
            let name = rightBtn.titleLabel?.text
            self.studname(name!)
            
            let clickResultName = self.appendName(name!)
            print("result = \(clickResultName)")
            
            let titleName = self.cellInfoModel?.titleName
            //判断现有数据是否包含拼接的字符串
            if titleName?.contanins(find: name!) == false {
                self.cellInfoModel?.titleName = "\(titleName!)_\(name!)"
                let resultName = self.cellInfoModel?.titleName
                self.titleLabel?.text = resultName!
            }
    
        }
    
    }
    
    

    6 : 创建字符串的宽展类, 实现判断字符串A是否包含字符串B

    extension String {
        func contanins(find: String) -> Bool {
            return self.range(of: find) != nil
        }
        
        func containsIgnoringCase(find: String) -> Bool {
            return self.range(of: find, options: .caseInsensitive) != nil
        }
    }
    

    7 : Swift 自定义Log封装

    /// log 封装
    /// - Parameters:
    ///   - message: 打印信息
    ///   - file: 表示当前文件
    ///   - functionName: 功能名
    ///   - lineNumber: 表示当前行数
    func WFLog<T>(_ message: T,
                   file: String = #file,
                   functionName: String = #function,
                   lineNumber: Int = #line) {
        #if DEBUG
        //functionName 方法名容易很长,可自行添加
        let filename = (file as NSString).lastPathComponent
        print("\(filename): \(lineNumber)-\(message)")
        #endif
    }
    

    8 : Swift 和OC 混合开发,引入Bridge桥接文件,可以参考这个朋友写的很详细

    iphone项目中,Swift 和OC混合开发, 写的很详细

    9 : Swift项目中使用SDWebViewImage,加载图片失败可以试下这个

    使用以下方法加载不出来图片
    
    let imageUrl: String = "http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p53688.jpg"
    self.imageView?.sd_setImage(with: URL.init(string: imageUrl), placeholderImage: UIImage.init(named: self.imageName!), options: SDWebImageOptions.continueInBackground, completed: { (image:UIImage?, error:Error!, SDImageCacheTypeMemory, url:URL!) in         
      print("error: \(String(describing: error))")
     })
    

    从错误信息可以看出是因为图片url是http的; Xcode 7以后,苹果就要求所有的网络请求都是安全的(HTTPS).所有如果本身的服务器不支持HTTPS请求的话就要修改Xcode的默认配置.

    只需要在项目的info.plist文件中添加一个字典

    App Transport Security Settings, 然后再装个字典中添加一个BOOL类型的键值对 Allow Arbitrary Loads 并设置为 YES即可,如下图, 重新run下项目测试下,还应该就解决了. 截屏2020-04-1322.25.06.png

    10 : Swift 集成下拉刷新和上拉加载更多控件

    Github地址,介绍特别详细
    使用Cocoapods集成 ESPullToRefresh 刷新库

    pod "ESPullToRefresh"
    
    • 设置下拉刷新
    self.tableView.es.addPullToRefresh {
        [unowned self] in
        /// 在这里做刷新相关事件
        /// ...
        /// 如果你的刷新事件成功,设置completion自动重置footer的状态
        self.tableView.es.stopPullToRefresh(completion: true)
        /// 设置ignoreFooter来处理不需要显示footer的情况
        self.tableView.es.stopPullToRefresh(completion: true, ignoreFooter: false)
        /// 进入界面需要自动刷新的可以设置下
        self.tableView.es.autoPullToRefresh()
    }
    
    • 设置上拉加载
    self.tableView.es.addInfiniteScrolling {
        [unowned self] in
        /// 在这里做加载更多相关事件
        /// ...
        /// 如果你的加载更多事件成功,调用es_stopLoadingMore()重置footer状态
        self.tableView.es.stopLoadingMore()
        /// 通过es_noticeNoMoreData()设置footer暂无数据状态
        self.tableView.es.noticeNoMoreData()
    }
    

    11 : 获取当前控制器

    extension UIViewController {
        
        /** 获取当前控制器 */
        static func current() -> UIViewController {
            let vc = UIApplication.shared.keyWindow?.rootViewController
            return UIViewController.findBest(vc: vc!)
        }
        
        private static func findBest(vc: UIViewController) -> UIViewController {
            if vc.presentedViewController != nil {
                return UIViewController.findBest(vc: vc.presentedViewController!)
            } else if vc.isKind(of: UISplitViewController.self) {
                let svc = vc as! UISplitViewController
                if svc.viewControllers.count > 0 {
                    return UIViewController.findBest(vc: svc.viewControllers.last!)
                } else {
                    return vc
                }
            } else if vc.isKind(of: UINavigationController.self) {
                let svc = vc as! UINavigationController
                if svc.viewControllers.count > 0 {
                    return UIViewController.findBest(vc: svc.topViewController!)
                } else {
                    return vc
                }
            } else if vc.isKind(of: UITabBarController.self) {
                let svc = vc as! UITabBarController
                if (svc.viewControllers?.count ?? 0) > 0 {
                    return UIViewController.findBest(vc: svc.selectedViewController!)
                } else {
                    return vc
                }
            } else {
                return vc
            }
        }
    }
    

    使用方法如下

    UIViewController.current()
    

    12 : 获取当前导航控制器

    方案一: 在控制器或view界面添加以下方法 , 直接获取

    ///获取当前视图所在导航控制器
        func currentNavViewController() -> UINavigationController? {
            var n = next
            while n != nil {
                if n is UINavigationController {
                    return n as? UINavigationController
                }
                n = n?.next
            }
            return nil
    }
    

    方案二: 统一获取
    使用上边获取当前控制器的方法,在获取导航控制器

    func kCurrentNavigationController () -> UINavigationController {
        ///获取当前视图所在导航控制器
        let vc = UIViewController.current()
        return vc.navigationController ?? UINavigationController.init()
    }
    

    13 : toast

    引用

    pod 'MCToast'
    

    MCToast使用说明

    Swift泛型协议的N种用法

    swift 中 Self 与self

    计算机知识学习git地址

    Demo地址(持续更新中)
    ps: 整理swift小知识,方便自己查找,小编是初学者,充实自我,从每一天开始,加油!!!

    相关文章

      网友评论

          本文标题:Swift 学习整理

          本文链接:https://www.haomeiwen.com/subject/vnefmhtx.html