美文网首页
iOS Swift5从0到1系列(二):学习UITabBarCo

iOS Swift5从0到1系列(二):学习UITabBarCo

作者: 青叶小小 | 来源:发表于2021-03-06 02:28 被阅读0次

    一、前言

    没想到本系列第一篇开局就能收获这么多朋友的喜爱与鼓励,让我更有动力继续本系列。

    之所有出的这么慢,也是因为,我希望尽量把每个知识点讲到位,哪怕你是零基础,致力想成员一名 iOSer 的朋友,也能够再学习本系列的时候,掌握知识细节,所以,每遇到我认为是一个需要展开分析的点的内容,我都会反复再三确认,并认真思考如何用最好的方式来呈现给大家。

    既然要做本系列,我们肯定要选择一个模仿的『对象』,而这个『对象』,如果大家之前有看过我分享的《抓包工具 Charles》,大家一定可以猜的出来,我们本系列将要模仿的『对象』是:\color{red}{京东APP}

    今天先仿京东APP的底部导航栏,如下图:

    jdapp-tabbar.png

    二、底部导航栏控制器(UITabBarController)

    我们打开京东APP,进入到它的主页,就能看到最底部有一排五个按钮,每个按钮都对应着一个页面(我们称之为 ViewController),因此,最底部我们称之为『底部导航栏』。

    源码注释:
    If more than five view controllers are added to a tab bar controller, only the first four will display.
    如果创建的个数大于5个,将会直接显示前4个。
    The rest will be accessible under an automatically generated More item.
    剩下的将会都收敛到一个叫作『更多』的按钮中。

    这也就是为何几乎绝大多数 APP 都只定义不超过 5 个按钮及对应的 ViewController 的原因;源码注释中,并没有说最少定义几个,不过,一般来说至少定义 2 个以上(如果定义为一个,虽然可以,但那使用 UITabBarController 就没有任何意义)。

    在正式开始学习使用前,我们先分析下 UIKit.UITabBarController 中的源码。

    2.1、UITabBarController 分析

    @available(iOS 2.0, *)
    open class UITabBarController : UIViewController, UITabBarDelegate, NSCoding {
        open var viewControllers: [UIViewController]?
        ......
    }
    

    我们看到:

    • UITabBarController 继承于 UIViewController;
    • 实现了 UITabBarDelegate 即 UITabBar(底部按钮的委托);
    • 以及 NSCoding(归档与反归档数据存取协议);
    • 定义了 UIViewController 对象可 nil 数组;

    2.2、扩展 UIViewController 分析

    extension UIViewController {
        // Automatically created lazily with the view controller's title if it's not set explicitly.
        open var tabBarItem: UITabBarItem!
        
        // If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.
        open var tabBarController: UITabBarController? { get } 
    }
    

    如上源码,对 UIViewController 进行了扩展,内置了 UITabBar 的按钮,即 tabBarItem,该按钮可以添加文件、图标、消息汽泡等。

    三、UITabBarController 的使用

    按照上一篇的内容,我们先创建工程,一切就绪如下:

    ready.png

    3.1、创建 MainTabBarController

    先创建一个『New Group』,然后『New File』,如下:

    MainTabBarController.png

    选择『Cocoa Touch Class』,Subclass of 选择 UITabBarController:

    SubClassOf.png

    3.2、添加 Group 及 5个 UIViewController

    5-vcs.png

    3.3、修改 AppDelegate.swift

    我们修改 AppDelegate.swift,让 window 的 rootViewController 为我们的 MainTabBarController:

    modify-app-delegate.png

    运行模拟器如下显示:

    tabbar-run.png

    最底部灰色区域就是底部导航 UITabBar。

    3.4、添加 icons

    因为现在 macOS App Store 已经不允许下载 app 包到电脑,因此只能去官网下载 Android APK包,zip 解压后,搜索『.png』文件,结果只发现了『分类』、『购物车』和『我的』三种图标,而『首页』和『发现』没有找到。往年,双11 京东 app 底部的 icons 都会变,所以,底部图标默认的应该不是我们现在看到的样子,但总之,不影响我们的 demo 学习。

    从 android apk 中拿到资源后,观察尺寸大小,将 40x40 的命名为 @2x,而 60x60 的命名为 @3x,如下:

    images.png

    然后选择 Xcode 项目中的『Assets.xcassets』,将上面的图标拖进去即可:

    drag-image.png

    释放后,Xcode 会自动识别,如下:

    after-drag.png

    3.5、实现 UITabBarController 功能

    代码如下(以下代码是经过反复优化过后的):

    //
    //  MainTabBarController.swift
    //  JDApp
    //
    //  Created by qingye on 2021/3/5.
    //
    
    import UIKit
    
    class MainTabBarController: UITabBarController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            initTabBar()
        }
        
        func initTabBar() {
            let home = HomeViewController()
            home.tabBarItem.title = "首页"
    
            let category = CategoryViewController()
            category.tabBarItem.title = "分类"
            category.tabBarItem.image = UIImage(named: "category.png")
    
            let found = FoundViewController()
            found.tabBarItem.title = "发现"
    
            let cart = CartViewController()
            cart.tabBarItem.title = "购物车"
            cart.tabBarItem.image = UIImage(named: "cart.png")
    
            let mine = MineViewController()
            mine.tabBarItem.title = "我的"
            mine.tabBarItem.image = UIImage(named: "mine.png")
    
            viewControllers = [home, category, found, cart, mine]
    
            // 设置 tabBar & tabBarItem
            setTabBarItemAttributes(bgColor: UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1))
        }
    
        /// 这种方式比较灵活
        func setTabBarItemAttributes(fontName: String = "Courier",
                                     fontSize: CGFloat = 14,
                                     normalColor: UIColor = .gray,
                                     selectedColor: UIColor = .red,
                                     bgColor: UIColor = .white) {
            // tabBarItem 文字大小
            var attributes: [NSAttributedString.Key: Any] = [.font: UIFont(name: fontName, size: fontSize)!]
            
            // tabBarItem 文字默认颜色
            attributes[.foregroundColor] = normalColor
            UITabBarItem.appearance().setTitleTextAttributes(attributes, for: .normal)
            
            // tabBarItem 文字选中颜色
            attributes[.foregroundColor] = selectedColor
            UITabBarItem.appearance().setTitleTextAttributes(attributes, for: .selected)
            
            // tabBar 文字、图片 统一选中高亮色
            tabBar.tintColor = selectedColor
            
            // tabBar 背景色
            tabBar.barTintColor = bgColor
        }
    }
    

    截图如下:

    src-all.png

    3.6、修改 HomeViewController 及 CategoryViewController

    • HomeViewController
    //
    //  HomeViewController.swift
    //  JDApp
    //
    //  Created by qingye on 2021/3/6.
    //
    
    import UIKit
    
    class HomeViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .green
            
            let label = UILabel(frame: CGRect.zero)
            label.text = "HomeViewController"
            label.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(label)
            
            NSLayoutConstraint.activate([
                label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
        }
    }
    
    • CategoryViewController
    //
    //  CategoryViewController.swift
    //  JDApp
    //
    //  Created by qingye on 2021/3/6.
    //
    
    import UIKit
    
    class CategoryViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let label = UILabel(frame: CGRect.zero)
            label.text = "CategoryViewController"
            label.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(label)
            
            NSLayoutConstraint.activate([
                label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
        }
    }
    

    3.7、运行模拟器

    run-home.png run-category.png

    好了,本篇分享就到此结束,如果大家有什么问题,也希望多交流,谢谢!源代码会在下几次分享后,整体上传!后续会再次编辑此文,也可继续关注,谢谢!

    相关文章

      网友评论

          本文标题:iOS Swift5从0到1系列(二):学习UITabBarCo

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