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文件中添加一个字典
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'
Demo地址(持续更新中)
ps: 整理swift小知识,方便自己查找,小编是初学者,充实自我,从每一天开始,加油!!!
网友评论