从头开始swift2.1 仿搜材通项目(三) 主流框架Tabbed的搭建

大家知道,我们在新建一个项目的时候,xcode就提供了一些模版框架给我们选择,其中比较常用的便是Tabbed Application,一旦选用这个模版创建好项目之后呢,会在StoryBoard中自动生成一系列的ViewController,非常方便(如下图),但仅仅只对个人开发者而言,团队开发的话如果把所有Controller都写到一个StoryBoard中,很有可能因为都修改过这个文件而提交时有冲突,现在我们就学习一下如何避免这种情况。

QQ20151219-1@2x.png

这里给大家推荐一个优秀的第三方TabBarController:CYLTabBarController,有点不足的是它是用Objective-C写的,不过正好我们可以再温习一下如何在Swift工程下引用Objective-C的开源工具。
继续上一节我们的工程,上一节我们是为项目添加了百度地图的支持,不过我们暂时先不用它,现在我们在finder中新建一个目录,放一些我们后面可能会使用到的第三方或者是我们自己编写的一些公共通用工具类,这也是我们后面的目的,打造一个Swift快速开发框架
现在我们来开始动手吧,在当前目录中新建目录 Library(以后我们的框架库) -> Resource(所有引用到的第三方开源工具) ,并在Resource中放入上面提到的CYLTabBarController。现在你的目录结构应该跟下面是一样的。

QQ20151219-2@2x.png

修改sctong-Bridging-Header.h,添加对CYLTabBar的引用

//百度地图
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入云检索功能所有的头文件
#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的头文件
#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周边雷达功能所有的头文件
#import <BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件

//新增CYLTabBar 
#import "CYLTabBarController.h"
#import "CYLTabBar.h"
#import "CYLPlusButton.h"

现在我们在项目根目录下也新建一些目录,初学者不要嫌这样很麻烦,你当然可以直接在Xcode中直接新建group,再到group下新建对应的文件就行,但这样在Xcode中看起来还正常,如果你到Finder下查看的话,会发现所有的文件全部并在根目录下的,那里你要找什么文件也不会很方便了,在Xcode支持创建Group时同时创建对应的文件夹之前,我们还是老老实实的在Finder中创建并拖拽进Xcode中吧。


QQ20151219-3@2x.png

我们将创建好的文件目录拖拽进Xcode,暂时只需要拖根目录,也就是Library及UI两个,现在你的结构应该跟图中的一样:


QQ20151219-4@2x.png

QQ20151219-5@2x.png

在Main下新建一个MainTabBarController,它就是以后程序的主界面了
QQ20151219-6@2x.png

之前我们看过android版的app,可以看到底部分别是首页、人脉、消息、我的,现在我们继续在Finder中分别创建对应的4个目录,Home、Connection、Message和Personal,中间的按钮我们后面再实现。


QQ20151219-7@2x.png

QQ20151219-8@2x.png

拖进Xcode中Main下:
QQ20151219-9@2x.png

分别在4个目录下创建一个StoryBoard,并拖入一个简单的ViewControll,这样如果团队开发的话我们就可以各自维护自己的SB并且不会冲突了。
QQ20151219-10@2x.png

QQ20151219-11@2x.png

好的我们现在回到MainTabBarController,修改其继承自CYLTabBarController,如果你没有找到这个类的话,请查看一下sctong-Bridging-Header是否添加了import。
//新增CYLTabBar 
#import "CYLTabBarController.h"
#import "CYLTabBar.h"
#import "CYLPlusButton.h"

下面我们修改MainTabBarController,


QQ20151219-12@2x.png

viewDidLoad中的实现

    /**
     经过我再次封装,这个方法可以直接不需要理会,后面我们继续扩展,以后就不需要再写viewDidLoad的方法了
     */
    override func viewDidLoad() {
        super.viewDidLoad()
        
        var tabBarItemsAttributes: [AnyObject] = []
        var viewControllers:[AnyObject] = []
        
        for i in 0 ... Title.count - 1 {
            let dict: [NSObject : AnyObject] = [
                CYLTabBarItemTitle: Title[i],
                CYLTabBarItemImage: Image[i],
                CYLTabBarItemSelectedImage: SelectedImage[i]
            ]
            let vc = UIStoryboard(name: StoryName[i], bundle: nil).instantiateInitialViewController()
            
            tabBarItemsAttributes.append(dict)
            viewControllers.append(vc!)
        }
        
        self.tabBarItemsAttributes = tabBarItemsAttributes
        self.viewControllers = viewControllers
    }
    ```
现在我们修改AppDelegate中的rootViewController为当前的MainTabBarController:
![QQ20151219-13@2x.png](http://upload-images.jianshu.io/upload_images/1190844-6ad274c3ae3ebbb5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后我们在模拟器上运行一下,选择6S\5S什么的随便了。
![QQ20151219-14@2x.png](http://upload-images.jianshu.io/upload_images/1190844-e5d77b26ace16241.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
噢,这里出了异常,不要怀疑这段代码,是我们之前有一步忘记操作了。
**回到之前我们建立的4个SB文件,都把is initial view Controller勾上,再次运行。**
![QQ20151219-15@2x.png](http://upload-images.jianshu.io/upload_images/1190844-a9e40084886170b6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这次我们看到,4个tab已经显示出来了,但因为没有设置导航,也没有放图片资源进去,所以图片和导航是看不到的。
![QQ20151219-16@2x.png](http://upload-images.jianshu.io/upload_images/1190844-9a30c4168f9be240.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
现在我们设置一下导航:
![QQ20151219-17@2x.png](http://upload-images.jianshu.io/upload_images/1190844-eaca5cefe2543cc8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://upload-images.jianshu.io/upload_images/1190844-51fcca9998e4fba0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
记得把4个都设置一下。我们再放入资源文件
![QQ20151219-19@2x.png](http://upload-images.jianshu.io/upload_images/1190844-1e51185a34de779a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
再次运行,图片和导航都正常的显示出来了。
![QQ20151219-20@2x.png](http://upload-images.jianshu.io/upload_images/1190844-c8809aa38cd4dfaf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我们把导航做得稍微漂亮一点,Info.plist中添加
<key>UIStatusBarTintParameters</key>
<dict>
    <key>UINavigationBar</key>
    <dict>
        <key>Style</key>
        <string>UIBarStyleDefault</string>
        <key>Translucent</key>
        <false/>
    </dict>
</dict>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
didFinishLaunchingWithOptions中添加
    application.statusBarStyle = UIStatusBarStyle.LightContent
    UINavigationBar.appearance().barTintColor = UIColor.init(red: 33/255, green: 150/255, blue: 243/255, alpha: 1)
    UINavigationBar.appearance().tintColor = UIColor.whiteColor()
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
再次运行,一个完美的上档次的主流导航UI框架就出现了。
![QQ20151219-21@2x.png](http://upload-images.jianshu.io/upload_images/1190844-641a80cb1539f042.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后我们来实现中间的按钮,在MainTabBarController中新建一个PlusButtonSubclass,

class PlusButtonSubclass : CYLPlusButton,CYLPlusButtonSubclassing{

class func plusButton() -> AnyObject! {
    let button:PlusButtonSubclass =  PlusButtonSubclass()

    //修改下按钮的大小
    button.frame.size.width = 50;
    button.frame.size.height = 50;

    button.setImage(UIImage(named: "icon_middle_add"), forState: UIControlState.Normal)
    button.titleLabel!.textAlignment = NSTextAlignment.Center;
    button.adjustsImageWhenHighlighted = false;
    button.addTarget(button, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
    
    return  button
}

//点击事件
func buttonClicked(sender:CYLPlusButton)
{
    print("hello mm")
}

override func layoutSubviews() {
    super.layoutSubviews()
    // 控件大小,间距大小
    let imageViewEdge   = self.bounds.size.width * 0.6;
    let centerOfView    = self.bounds.size.width * 0.5;
    let labelLineHeight = self.titleLabel!.font.lineHeight;
    //        let verticalMarginT = self.bounds.size.height - labelLineHeight - imageViewEdge;
    //        let verticalMargin  = verticalMarginT / 2;
    
    // imageView 和 titleLabel 中心的 Y 值
    //        _  = verticalMargin + imageViewEdge * 0.5;
    let centerOfTitleLabel = imageViewEdge  + labelLineHeight + 2;
    
    //imageView position 位置
    self.imageView!.bounds = CGRectMake(0, 0, 36, 36);
    self.imageView!.center = CGPointMake(centerOfView, 0)//centerOfImageView * 2 );
    
    //title position 位置
    self.titleLabel!.bounds = CGRectMake(0, 0, self.bounds.size.width, labelLineHeight);
    self.titleLabel!.center = CGPointMake(centerOfView, centerOfTitleLabel);

}

}在didFinishLaunchingWithOptions中第一行加入PlusButtonSubclass.registerSubclass()```

有人遇到的这个buttonClicked 事件没响应,是因为你没有设置按钮的宽和高!自己打印下按钮的frame,就知道了!然后在func plusButton()这个方法里面设置宽和高就可以了!(如果在layoutSubviews中添加的话初始位置会不正确)

 //修改下按钮的大小
 button.frame.size.width = 100;
 button.frame.size.height = 100;

再次运行,中间的按钮已经出来了,同学们可以根据自己的需求在layoutSubviews中修改一下坐标,达到不同的效果。

QQ20151219-22@2x.png

OK本节到此结束。
Git地址:https://github.com/bxcx/sctong
本节分支:https://github.com/bxcx/sctong/tree/2nd_tabbed

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容