亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

再造輪子之網易彩票-第二季(IOS篇bysixleaves)

2019-11-14 18:45:14
字體:
來源:轉載
供稿:網友

02-彩票項目第二季

2.封裝SWPTabBar方式一

接著我們思考如何進行封裝。前面已經將過了為什么要封裝, 和封裝達到的效果。這里我們主要有兩種封裝方式,分別是站在不同的角度上看待問題。雖然角度不同但是內部最核心的思想還是一樣的,就是屏蔽控件內部是如何構造的細節, 為外界提供簡單容易理解的接口。方式一: SWPTabBar屏蔽所有內在細節,只需提供要創建的控件個數。就可以創建出SWPTabBar的大體框架。接著有幾個方法可以用來設置TabBar內部按鈕的數據。簡單來說只需提供1. 設置按鈕個數。2. 設置按鈕數據的接口。

注意: 那么我們如何保證接口的健壯性, 要知道如果有用戶反復或多次設置按鈕個數,那么我們要做到的效果是重新構造TabBar新的內部,而不能造成按鈕的重復累加。這也是我們設計接口時候要考慮的一點,該接口是否方便使用, 時候多次使用會出錯等等許多細節。并不是所設計接口就是隨便的提供個方法的調用這么簡單,這需要經驗的積累。

首先看下面代碼和注釋:

-(void)viewDidLoad {    [super viewDidLoad];        // 創建自定義的tabBar控件    SWPTabBar * tabBar = [[SWPTabBar alloc] init];        tabBar.frame = self.tabBar.frame;        // 設置控件內部的按鈕個數    tabBar.numberOfBarButton = 5;        // 控件代理對象, 用于監聽對象    tabBar.delegate = self;        // 蓋在原來tabBar之上    [self.view addSubview: tabBar];}

看如上代碼, 我們的意圖很明顯,就是用我們自定義的SWPTabBar蓋在UITabBar上,造成一種以假亂真的效果。當然你也可以選擇把UITabBar刪了,在覆蓋上去,減少不必要的渲染。接著我們就要關注內部細節的實現。這才是我們要掌握的重點。先看如下主線

分析:1.首先我們可以選擇在initWithFrame中添加控件。為什么不在init呢,因為用戶可能會直接調用initWithFrame方法,這樣就不正確了。但是init方法其實還會調用initWithFrame方法,所以我們重寫initWithFrame方法是最保險的方式。2.必須在確定了SWPTabBar的尺寸之后再計算其子控件的位置和尺寸, 所以我們重寫layoutSubViews方法。

分析中的1和2代碼分別如下:

-(instancetype)initWithFrame:(CGRect)frame {        if (self = [super initWithFrame: frame]) {            [self setup]    }        return self;}-(void)setup {        for (int i = 0; i < self.numberOfBarButton; i++) {                SWPButton * button = [[SWPButton alloc] init];                // 設置按鈕不同狀態的圖片        [button setBackgroundImage:[UIImage imageNamed:@"TabBar1"] forState: UIControlStateNormal];                [button setBackgroundImage:[UIImage imageNamed:@"TabBar1Sel"] forState: UIControlStateSelected];                // 為每個按鈕綁定tag, 方便后面切換為不同的UINavigationController        button.tag = i;            // 添加監聽        [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];                // 設置初始選中按鈕        if ( 0 == i) {                        [self buttonClicked: button];        }                [self addSubview: button];    }        // 設置斷言, 控件個數為按鈕個數    assert(self.subviews.count == self.numberOfBarButton);}

快速的瀏覽一下這段代碼,抓住起重點功能理解即可。為什么我們要抽出setup把添加構造控件內部的代碼都放在這, 其一、是為了提高代碼的復用。因為現在我們只是在initWithFrame中構造,當我們可用可能會提供xib的方式進行構造,在xib方式中,我們一般在awakeFromNib中進行控件的構造,你可以把它理解為相當于xib的初始化方法。其二、是為了在出錯的時候方便調試,一般一個函數或者方法的功能超過了12行以上不利于后面項目的維護,當然這也不能定死的看。像有的方法,剛好是20行已經是一個功能,而且也不能在抽取,這時候不要死腦筋非得把該方法進行拆分。拆分的是為了復用和調試。代碼不難理解,有疑問的可以給我留言。我們主要掌握的是整個的思路。具體細節需要你們自己進行代碼的編寫,遇到問題在解決,那才有所意義,不要在意細節。

以下代碼為重寫layoutSubViews實現內部子控件的位置尺寸的確定。

- (void)layoutSubviews {        [super layoutSubviews];        // 按鈕的尺寸, Y坐標值    CGFloat buttonW = self.frame.size.width / self.numberOfBarButton;    CGFloat buttonH = self.frame.size.height;    CGFloat buttonY = 0.0;        // 遍歷按鈕,設置尺寸、位置    for (int i = 0; i < self.numberOfBarButton; i++) {                CGFloat buttonX = i * buttonW;                SWPButton * button = self.subviews[i];                button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);                button.backgroundColor = [UIColor redColor];    }}

分析:好了運行程序,自定義的SWPTabBar是不是不正常?為什么對應的按鈕個數,無法顯示出來。仔細思考下,不難發現。我們是在創建完SWPTabBar之后,才來設置按鈕的個數。也就是說此時SWPTabBar已經構建后了,我們此時設置的個數根本就沒有用!。那么怎么解決,我是通過重寫numberOfButtons的setter方法,將setup方法放在setter中。這樣,我們就可以再設置按鈕個數的時候,再來構造該控件的內部。此時發現了setup的好處沒。入果你把這些代碼直接方法initWithFrame中, 那么現在就必須先復制,將initWithFrame刪除,在粘貼到setter方法中。如果有多個自定義的控件,一個個這么做,我想你會瘋了的。問題:我們需要關注一個細節,什么不是所不要在意細節!該在意的要在意,不該在意的要忽略,要看關注點!就是如果用戶多次調用這個setter方法, 會造成按鈕的重復添加。這不是我們要的效果。所以我們需要在這之前移除SWPTabBar內部所有的控件。再進行添加。所以我實現了 clear方法,具體刪除細節看代碼,思路很簡單:逐個遍歷,刪除。

修改后的代碼如下

- (instancetype)initWithFrame:(CGRect)frame {        if (self = [super initWithFrame: frame]) {            }        return self;}- (void)setNumberOfBarButton:(NSUInteger)numberOfBarButton {        _numberOfBarButton = numberOfBarButton;        // 先刪除存在的按鈕    [self clear];        // 先添加按鈕    [self setup];}- (void)clear {        [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];}

效果圖如下:

點擊跳轉按鈕的效果圖

3.改進我們知道, UITabBarController中的幾個子控制器是UINavagationController,當點擊下面SWPTabBar控件中的按鈕時候,進行子控制器的切換, 當點擊UINavigationController上面的按鈕進行跳轉時候,實際上是UINavigationController對其子控制器進行壓棧操作?,F在我們想實現的效果是, 當UINavigationController切換其子控制器的時候, 新的控制器不顯示出UITabBar, 我們可以通過SB中操作來勾選新控制器的Hide Bar Buttom &hellip;來對UITabBar進行隱藏, 然而我們自定義的SWPTabBar并不是UITabBar的子控件而是其兄弟控件, 所以設置的效果是作用在UITabBar上,又因為SWPTabBar比較后面添加, 蓋在了上面, 所以是看不到效果的。此時我們只需要換種思路, 把SWPTabBar直接加進UITabBar控件中, 并完全覆蓋它即可實現這樣的效果。

修改的代碼如下:(關注第6行和第12行,相信不難理解)

- (void)viewDidLoad {    [super viewDidLoad];        SWPTabBar * tabBar = [[SWPTabBar alloc] init];        tabBar.frame = self.tabBar.bounds;        tabBar.numberOfBarButton = 5;        tabBar.delegate = self;        [self.tabBar addSubview: tabBar];    }

思考:手動 VS 代碼

我們的確可以通過勾選Hide Bar Buttom …來隱藏UITabBar,但是當控制器達到一定數量時候, 這種做法的做事效率太低, 這就好比快速排序和冒泡排序,這兩種排序在排序個數很少的時候, 冒泡排序取得的時間效率比快速排序還低, 但是當操作某個值后,快速排序有十分好的時間效率。依次類比, 我們也要知道代碼的方式, 這樣遇到熟練一多的情況, 可以幫助我們提高項目的開發速度。說了太多廢話,仁者見仁,智者見智。

    實現具體細節如下:    1.通過自定義的SWPNavigationController重寫管理其子控制器棧結構的入棧方法。來攔截push操作    ,在push之前, 設置隱藏底部的UITabBar。    2.調用父類的入棧操作,完成父類自己的事情(將UIViewController入棧)。    代碼如下:    3.到sb中分別更改UINavigationController的關聯類
// SWPNavigationController- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {    viewController.hidesBottomBarWhenPushed = YES;    [super pushViewController:viewController animated:animated];}

改進后點擊跳轉按鈕的效果圖

可能你會發現我一直都沒講怎么實現SWPTabBar中如何切換到不同的UINavigationController,這個我們放在下一節介紹,現在我們只需要關注以上的重點,并理解之即可。

    1.自定義類中,繼承 + 重寫攔截了要調用的方法。    2.UINavigationController與UITabBar管理子控制器的方式    3.如何自定義控件(setup、layoutSubViews)    4.如何更加全面的考慮設計的接口

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品毛片网大全| 日韩美女免费视频| 亚洲老头同性xxxxx| 久久久久久久久久久亚洲| 国产999精品| 欧美日韩国产在线播放| 亚洲高清在线观看| 久久久精品一区二区三区| 久久影院中文字幕| 久久精品夜夜夜夜夜久久| 黄色一区二区在线| 欧美xxxx14xxxxx性爽| 国产精品久久久久免费a∨| 庆余年2免费日韩剧观看大牛| 国产成人精品在线播放| 88国产精品欧美一区二区三区| 国产精品成熟老女人| 亚洲电影免费观看高清完整版| 成人黄色在线免费| 精品调教chinesegay| 一本久久综合亚洲鲁鲁| 91黑丝在线观看| 欧美香蕉大胸在线视频观看| 日韩精品视频中文在线观看| 久久九九有精品国产23| 国产精品亚洲一区二区三区| 亚洲欧美日韩精品久久奇米色影视| 91久久久久久久一区二区| 日韩有码在线观看| 亚洲国产天堂网精品网站| 久久综合九色九九| 日本一区二区在线播放| 久久久久久久久久久成人| 国产精自产拍久久久久久蜜| 精品一区二区三区四区在线| 国产精品电影一区| 久久久久久一区二区三区| 日韩在线视频一区| 亚洲欧美在线免费| 美日韩丰满少妇在线观看| 亚洲国产欧美一区二区三区久久| 91国产高清在线| 亚洲mm色国产网站| 亚洲精品小视频在线观看| 国产精品日韩av| 中文字幕不卡在线视频极品| 亚洲视频在线观看视频| 4438全国成人免费| 亚洲第一精品久久忘忧草社区| 国产精品偷伦免费视频观看的| 欧洲精品在线视频| 日韩av一区二区在线| 久久韩国免费视频| 91久久精品美女| 久久久久久久成人| 亚洲护士老师的毛茸茸最新章节| 成人久久久久久| 亚洲高清在线观看| 国产精品黄视频| 俺去了亚洲欧美日韩| 丝袜情趣国产精品| 亚洲福利视频在线| 日韩**中文字幕毛片| 91麻豆国产语对白在线观看| 国产精品白嫩初高中害羞小美女| 国产精品高精视频免费| 成人网址在线观看| 亚洲成在人线av| xvideos成人免费中文版| 日韩av一区在线观看| 亚洲免费视频在线观看| 中文字幕日韩在线观看| 人妖精品videosex性欧美| 欧美怡红院视频一区二区三区| 欧美日韩国产精品一区二区不卡中文| 日本欧美精品在线| 国产精品国产三级国产aⅴ浪潮| 精品国产依人香蕉在线精品| 国产日韩在线一区| 精品国内产的精品视频在线观看| 亚洲黄色av网站| 欧美日韩视频免费播放| 成人黄色影片在线| 一区二区在线免费视频| 伊人久久综合97精品| 国产精品aaa| 欧美成人激情图片网| 欧美一级淫片播放口| 欧美日韩精品国产| 精品无码久久久久久国产| 亚洲成人久久久| 亚洲男人天堂久| 欧美大片大片在线播放| 日韩在线视频观看正片免费网站| 亚洲欧美在线一区二区| 亚洲精品v天堂中文字幕| 日韩高清电影好看的电视剧电影| 久久久国产一区二区三区| 国产精品亚洲片夜色在线| 美女精品久久久| 亚洲欧美999| 国内揄拍国内精品少妇国语| 国产成人av网址| 精品国产欧美一区二区五十路| 亚洲电影免费观看高清| www.亚洲天堂| 亚洲天堂久久av| 久久综合免费视频影院| 中文字幕国产亚洲2019| 国产精品免费看久久久香蕉| 久久99久久亚洲国产| 久久91精品国产91久久久| 亚洲男人第一网站| 久久久久久久久久久国产| 96pao国产成视频永久免费| 性欧美办公室18xxxxhd| 日本午夜人人精品| 中文字幕久久精品| 亚洲一区二区三区在线免费观看| 精品magnet| 亚洲欧美制服丝袜| 懂色aⅴ精品一区二区三区蜜月| 亚洲精品久久在线| 国产主播欧美精品| 国产91ⅴ在线精品免费观看| 中文字幕日韩欧美在线视频| 欧美一区第一页| 久久亚洲精品毛片| 亚洲激情在线视频| 日韩av片永久免费网站| 亚洲一区二区免费在线| 亚洲人午夜精品免费| 国产成人精品优优av| 视频直播国产精品| 亚洲国产一区二区三区在线观看| 日本成熟性欧美| 亚洲国产天堂久久国产91| 日韩黄色av网站| 亚洲精品国产精品国产自| 亚洲综合精品一区二区| 在线观看欧美成人| 亚洲摸下面视频| 久久精品91久久香蕉加勒比| 国产精品白嫩初高中害羞小美女| 色中色综合影院手机版在线观看| 日韩va亚洲va欧洲va国产| 国产精品入口日韩视频大尺度| 久久精品一本久久99精品| 久久久久久久久久久91| 2019中文字幕在线免费观看| 福利视频一区二区| 少妇高潮久久77777| 91久久精品美女高潮| 日本免费久久高清视频| 中文字幕最新精品| 日韩免费在线视频| 色多多国产成人永久免费网站| 一区二区国产精品视频| 日韩av在线网址| 97人洗澡人人免费公开视频碰碰碰| 综合欧美国产视频二区| 亚洲精品国产精品国自产在线| 亚洲激情成人网| 国产成人精品综合久久久|