仿制新浪微博iOS客户端之三-自定义TabBar

  继续上一篇文章的进度,我们实际完成了微博基本框架的搭建,具体实现的效果如下左图,但我们实际需要实现的效果为右图,除去主要的页面内容不谈,仅仅下面的TabBar距离我们的需求就有相当的差距。因此本文着重于实现需要的效果。

                            

  再简要汇总一下我们的需求:

  1.我们要在TabBar原有四个按钮的基础上,再增加一个按钮,作为撰写微博的入口;

  2.新加入的按钮必须和原有按钮一起,均匀分布在TabBar上;

  3.新加入的按钮只有图片,没有文字。

  需求汇总如上,下面我们先进行一下分析和测试:

  1.在TabBarController上直接拖拽一个UITabBarItem,经测试,无法拖上,此方式无法实现需求;

  2.新创建ViewController,拖拽一个UITabBar,作为测试,直接修改默认的两个TabBarItem中的其中一个,测试结果如下: 

  使用此种方式后,TabBarItem的图片完全无法正常显示,并且图片位置偏上,与要求不符;并且这种方式将改变原有的界面架构,因此这种方案也被放弃;

  以上两种方案均不能达到效果,也就意味着,要实现想要的效果,就只能使用最后一个办法:自定义TabBar。

一、自定义控件

  在iOS中,只要是能在屏幕上显示的控件,那就可以进行自定义。因此,当系统提供的控件类型无法满足使用需要时,使用自定义控件就是最好、最快捷的实现方式。

二、自定义TabBar

  方案确定后,立刻开始实施。

  创建UITabBar子类MainTabBar,并设置TabBarController中TabBar继承的类为MainTabBar如下:

  自此,设置的部分完毕,开始进入代码:

  1.创建按钮并添加到TabBar中。

  要往TabBar中添加按钮,首先就要创建按钮。

 1     /// 懒加载撰写按钮,设置图片并添加到TabBar中
 2     lazy var composeButton: UIButton = {
 3         let btn = UIButton()
 4         btn.setImage(UIImage(named: "tabbar_compose_icon_add"), forState: UIControlState.Normal)
 5         btn.setImage(UIImage(named: "tabbar_compose_icon_add_highlighted"), forState: UIControlState.Highlighted)
 6         btn.setBackgroundImage(UIImage(named: "tabbar_compose_button"), forState: UIControlState.Normal)
 7         btn.setBackgroundImage(UIImage(named: "tabbar_compose_button_highlighted"), forState: UIControlState.Highlighted)
 8         // 添加到父控件中
 9         self.addSubview(btn)
10
11         return btn
12     }()

  2.调整按钮布局

  仅仅添加按钮,只能证明在逻辑上,TabBar有一个按钮子控件,但是并不足以显示到屏幕上,如果要显示出来,必须有准确的位置和尺寸才行。

  对于有子控件的控件来说,每一次对子控件位置的调整都会调用其自身的 layoutSubviews 方法,因此我们可以先在这个方法中测试一番,为后面的工作做准备。实际测试的结果如下:

  我们可以发现,在程序运行之后,layoutSubviews 方法被调用了两次,并且每次都打印出了6个子控件,除去对应四个子视图控制器的按钮外,还有另外两个控件,并且每一个控件都有详细的 位置、尺寸等信息。

  但是我们只需要关注其中的四个按钮,原因是我们仅需要对按钮的位置进行调整,再在中间位置插入我们创建的按钮即可。而这四个按钮相对于另外两个控件最大的区别是这四个按钮是响应者类型,而另外两个控件却不是,从它们的 userInteractionEnabled = NO 就可以看得出来。

  初始代码和实现效果分别如左、右图:

  这事我们发现应该居于右侧的两个按钮也靠到了左边,因此需要再做调整,并加上对中央撰写按钮的尺寸设置。最终实现如下:

    private let buttonCount = 5

    override func layoutSubviews() {
        super.layoutSubviews()

        /// 设置每个按钮的宽高和基准尺寸
        let w = self.bounds.width / CGFloat(buttonCount)
        let h = self.bounds.height
        let frame = CGRectMake(0, 0, w, h)

        var index: CGFloat = 0
        for view in self.subviews as! [UIView] {
            if (view is UIControl && !(view is UIButton)) {
                /**
                *  当前控件是响应者对象,并且不是 UIButton 类型时参照设置尺寸位置
                */
                view.frame = CGRectOffset(frame, index * w, 0)
                index += (index == 1) ? 2 : 1
            }
        }
        /**
        *  设置撰写按钮的尺寸和位置
        */
        self.composeButton.frame = frame
        self.composeButton.center = CGPointMake(self.bounds.width * 0.5, self.bounds.height * 0.5 )
    }

  3.设置撰写按钮的点击事件

  撰写按钮将在后续执行相应的操作,因此也是需要响应事件的,我们在这里就为撰写按钮添加点击事件。

  回到最初始的 MainTabBarController 类中,调整 viewDidLoad 方法,给撰写按钮添加点击事件,同时实现点击事件所调用的方法,并测试如下:

  至此,自定义TabBar的工作全部完成。

  杂谈:

  1.开发思路

  在实际投入开发之前,开发人员通常并不能十分的确定应当使用何种方式或者手段完成开发任务,因此在伴随开发过程中,开发人员通常是边尝试边开发,不同的尝试各种方案,最后找出可以实现的方案(也有可能此时找到的方案并不是最佳的)。因此在我们平时的开发中,对于独立性比较强或者独立性较强的功能或者模块,可以采用在另一个项目中测试、完成、实现,然后再移植到正常开发的代码中的模式。这种方式也是对正常开发影响最小的一种方法。

  有的开发者在收到需求后,喜欢找一个自己认为可能实现的方式,然后进行开发,并寄希望一次运行调试成功,如果遇到了问题,一旦原本的方案走不通,便有可能放弃,重新开始。而实际上,遇到bug和问题是开发人员的家常便饭,因此,这种方式起始并不可取。在这里我建议 “还没有能够久经考验的开发模式” 的开发人员遵循“从需求倒推”的开发方式和思路。

  在苹果目前提供的解决方案中,除去非常尖端的问题无法实现,其他的那些所谓“高大上”的难题都是可以解决的,前提是能找到合适的解决方案,除了在第一点中所说的多尝试,更重要的是利用倒推的方法,可以逐步理清方案中所使用的技术点和思路,这也是我推荐这个方式的最重要的原因。

  2.打印调试信息

  在开发中,开发者通常使用打印调试信息的方式来判断代码逻辑是否正确。但由于目前 Swift 语言的输出还不够智能,因此打印出来的结果通常都直接串连在一起。而 OC 和 Swift 之间有着良好的互通性,并且 OC 在打印调试信息时的格式是非常干净和整齐的,因此在打印 Swift 的调试信息时,可以将 Swift 对象转换为 OC 对象,以获得更清晰、明确的结果。

时间: 2024-12-10 09:46:49

仿制新浪微博iOS客户端之三-自定义TabBar的相关文章

仿制新浪微博iOS客户端之二-项目基础搭建及相关设置

上一次的文章主要提到了仿制新浪微博所用到的一些技术和知识点,那本文就开始进入正式的项目实施阶段了.首先要做的自然是项目的创建和相关的设置,以及基础框架的搭建了. 一.项目创建及相关设置 1.项目创建 现在越来越多的的公司开始使用Swift开发iOS和AppleWatch的项目,因此此次我们的开发也使用Swift语言来进行,新建项目,设置如下: 既然是仿制,自然可以当成是一个练习,项目名称:“WeiboTest”,编程语言选择“Swift”.然后“下一步”直到创建完成. 2.应用图标设置 将应用图

仿制新浪微博iOS客户端之一-序言

新浪微博是现在各个互联网平台上都使用得非常频繁的app之一,在其上拥有大量的用户,同时,其app的设计也反映了当前移动应用的主流开发趋势.因此在此基础上,对其app的仿制也有利于对当今app的开发技术的掌握.下面就开始仿制自己的新浪微博项目吧! 在本项目中,我们会使用到主流开发架构.OAuth认证授权登录.自动布局.二维码扫描.Emoji表情文字.自定义图片查看器.数据库SQLite等功能和技术,敬请期待! 一.架构方式 目前主流的多界面的移动app开发中,普遍的使用 TabBarControl

仿制新浪微博iOS客户端之四-未登录页面处理

写在最前:非常抱歉,前期因为个人原因有二十多天的时间没有再继续更新这个专题,期间仅仅是完成了苹果官方的UIStackView的文档的翻译.在这里我们将继续未完成的任务,继续做下去!现在继续! 一.前期总结 在完成第三篇的任务后,我们实际上完成的效果如下: 目前我们已经能保证界面的顺利切换,并且给微博的撰写按钮预留了点击事件接口,再下一步,我们将要完成在用户登录前的所有准备工作. 二.抽取基类 目前我们在首页.消息.发现.我这四个界面中使用的都是UITableViewController来加载和显

仿新浪微博IOS客户端(v5.2.8)——自定义UITabBar替换系统默认的(添加“+”号按钮)

转载请标明出处:http://blog.csdn.net/android_ls/article/details/45896395 声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片. 自定义UITabBar替换系统默认的,目的是为了在UITabBar中间位置添加一个"+号按钮",下面我们来聊聊具体的实现. 1.自定义WBTabBar,让其继承自UITabBar,代码如下: // // WBT

仿新浪微博IOS客户端(v5.2.8)——设置导航栏外观

转载请标明出处:http://blog.csdn.net/android_ls/article/details/45849447 声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片. 一. 在Xcode6下添加.pch文件 对于使用惯了之前版本Xcode的朋友来说,在系统提醒之下升级到Xcode 6之后,发现新建项目后Xcode不再帮我们创建.pch文件了.可是我们已经习惯了,把一些在很多地方都用的宏

仿新浪微博IOS客户端(v5.2.8)——下拉菜单栏的实现

转载请标明出处:http://blog.csdn.net/android_ls/article/details/45877983 声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片. 接着上一篇博文,这篇我们来聊聊新浪微博导航栏上,点击中间部分的标题(titleView)弹出的下拉菜单是如何实现. 1.自定义导航栏中间的titleView,代码如下: // 设置导航栏中间的titleView _tit

仿新浪微博IOS客户端(v5.2.8)——搭建项目基本框架

转载请标明出处:http://blog.csdn.net/android_ls/article/details/45827719 声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片. 最近我打算利用业余时间,仿下新浪微博IOS客户端,至于能写到哪里我也不确定,能写多少就写多少吧,下面我们开始项目的基本搭建: 1.打开Xcode选择创建新项目,并创建各个模块的目录结构,完成后项目的目录结构如下图: 2.

ios中解决自定义tabbar跳转隐藏问题的方法

在ios开发(http://www.maiziedu.com/course/ios/)中,如何自定义tabbar高度的跳转隐藏问题,比如和系统自带的tabbar高度不一样导致的有一条线的问题,还有push时动画效果等等一些列问题不在这里累述了,当然,思路有很多,可以参考以上链接自己琢磨琢磨,好了,下面直接上个人认为完美解决办法. 需求 1.自定义tabbar,不用系统的tabbar 2.第二点需求是自定义tabbar的高度和系统的不一样,系统的tabbar高度为49,就是因为这点导致第三个需求有

IOS开发-关于自定义TabBar条

今天在做项目的时候,突然有一个模块需要自定义TabBar条. 在平常很多做项目的时候,都没有去自定义过,大部分都是使用系统自带的.今天整理一个自定义TabBar条的步骤. 首先看下我们最终实现的效果: 首先需要继承UItabBar自定义一个自己的tabBar .h #import <UIKit/UIKit.h> @class THTabBar; @protocol THTabBarDelegate <UITabBarDelegate> @optional - (void)tabBa