国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

再造輪子之網易彩票-第二季(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對其子控制器進行壓棧操作。現在我們想實現的效果是, 當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.如何更加全面的考慮設計的接口

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江口县| 云霄县| 富宁县| 原平市| 黄梅县| 穆棱市| 榆林市| 鄂州市| 苏尼特左旗| 大关县| 闵行区| 阳山县| 南宫市| 宜春市| 宜州市| 古浪县| 鸡西市| 社旗县| 南澳县| 伊川县| 隆昌县| 秀山| 房产| 芮城县| 龙陵县| 瑞金市| 盘山县| 碌曲县| 镇江市| 南郑县| 偃师市| 平谷区| 汶上县| 百色市| 精河县| 新建县| 五大连池市| 昌图县| 资中县| 太仆寺旗| 遂平县|