小白實(shí)戰(zhàn)之玩轉(zhuǎn)微博(第二回)

今天的內(nèi)容也是關(guān)于首頁(yè)架構(gòu)的實(shí)現(xiàn),大概分為三塊.

  • 第一點(diǎn)是關(guān)于自定義的searchBar 由于大家項(xiàng)目中經(jīng)常有些控件是系統(tǒng)控件不能實(shí)現(xiàn)的,或者是經(jīng)常使用的,但是不是在一個(gè)頁(yè)面.所以我會(huì)使用自定義控件的方法進(jìn)行封裝.
  • 第二點(diǎn)是關(guān)于自定義的menu蒙版的效果,也是對(duì)于不同的view回頭內(nèi)容的封裝,大家可以進(jìn)行思考.
  • 最后一點(diǎn)的就是關(guān)于TabBar條上添加一個(gè)加號(hào)按鈕,這個(gè)時(shí)候也是采取的自定義TabBar的方法,強(qiáng)行在中間添加一個(gè)按鈕.
今天的內(nèi)容都是有關(guān)于控件的自定義跟封裝,看起來(lái)很簡(jiǎn)單,但是相比知識(shí)點(diǎn)是少了一點(diǎn),但是對(duì)于思想上的提升也是很有幫助,對(duì)于大家的代碼邏輯以及以后代碼的嚴(yán)謹(jǐn)也很有基礎(chǔ).

GIF


第二天內(nèi)容.gif

代碼如下
  • 第一點(diǎn)有關(guān)于自定義的searchBar的封裝,在此之前博主想說(shuō)對(duì)于這種經(jīng)常使用到的控件如果是想多次利用封裝好是用分類還是用繼承好呢.博主覺(jué)得如果是UI控件的話就使用繼承,一個(gè)是在創(chuàng)建的時(shí)候,不需要知道你內(nèi)部是怎么實(shí)現(xiàn),二是知道你使用的名字就跟想用的完全一樣.一看就知道這個(gè)控件是做什么的,不要點(diǎn)進(jìn)去看是什么控件.
+ (instancetype)searchBar {

    WKSearchBar *searchBar = [[WKSearchBar alloc]init];
    searchBar.background = [UIImage resizableImage:@"searchbar_textfield_background"];
    searchBar.width = [UIScreen mainScreen].bounds.size.width;
    searchBar.height = 30;
    
    
    UIImageView *leftView = [[UIImageView alloc]init];
    leftView.image = [UIImage imageNamed:@"searchbar_textfield_search_icon"];
    searchBar.leftView =leftView;
    searchBar.leftViewMode = UITextFieldViewModeAlways;
    leftView.width = 30;
    leftView.height = 30;
    leftView.contentMode = UIViewContentModeCenter;
    
    searchBar.clearButtonMode = UITextFieldViewModeWhileEditing;
    return searchBar;
}
  • 第二點(diǎn),是有關(guān)于自定義的那干view.由于經(jīng)常使用到內(nèi)部的控件.也是進(jìn)行封裝的,其實(shí)就是一個(gè)UIImageView 跟 UIButton. 對(duì)于點(diǎn)擊到UIImageView之外的地方就直接從窗口上移除.這里就提供了好幾種接口給大家展示.大家可以看源碼就知道.



#import <UIKit/UIKit.h>
@class WKPopMenu;

@protocol WKPopMenuDelegate <NSObject>

@optional
- (void)popMenuDidChangeImageRocation: (WKPopMenu *)popMenu;

@end

@interface WKPopMenu : UIView

@property (nonatomic,weak)id<WKPopMenuDelegate> delegate;

- (instancetype)initWith: (UIView *)contentView;

+ (instancetype)popMenuWith: (UIView *)contentView;

- (void)showInrect: (CGRect)rect;

- (void)dismiss;

@end

- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
        
        self.frame = [UIScreen mainScreen].bounds;
        UIButton *clearBtn = [[UIButton alloc]init];
//        [clearBtn setBackgroundColor:[UIColor redColor]];
        [clearBtn addTarget:self action:@selector(clickClearBtn) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:clearBtn];
        self.clearBtn = clearBtn;
        
        UIImageView *content = [[UIImageView alloc]init];
//        content.backgroundColor = [UIColor yellowColor];
        content.image = [UIImage resizableImage:@"popover_background"];
        content.userInteractionEnabled = YES;
        [self addSubview:content];
        self.content = content;
    }
    return self;
}

- (void)clickClearBtn {
    
    [self dismiss];

}

- (void)layoutSubviews {

    [super layoutSubviews];
    
    
    self.clearBtn.frame = self.bounds;
    
    
}

- (instancetype)initWith: (UIView *)contentView {

    if (self = [super init]) {
        
        self.contentView = contentView;
        
    }
    return self;
}

+ (instancetype)popMenuWith: (UIView *)contentView{
    
   return [[WKPopMenu alloc]initWith:contentView];
    
}

- (void)showInrect: (CGRect)rect{

    UIWindow *window = (UIWindow *)[UIApplication sharedApplication].keyWindow;

    [window addSubview:self];
    self.content.frame = rect;
    
    [self.content addSubview:self.contentView];
    
    CGFloat topMargin = 10;
    CGFloat leftMargin = 5;
    CGFloat rightMargin = 5;
    CGFloat bottonMargin = 5;
    
    self.contentView.x = leftMargin;
    self.contentView.y = topMargin;
    self.contentView.width = self.content.width - leftMargin - rightMargin;
    self.contentView.height = self.content.height - topMargin - bottonMargin;
    
}

- (void)dismiss {

    if ([self.delegate respondsToSelector:@selector(popMenuDidChangeImageRocation:)]) {
        
        [self.delegate popMenuDidChangeImageRocation:self];
        
    }
    
    [self removeFromSuperview];
    
}

  • 最后一點(diǎn)就是關(guān)于在自定義的tabBar上添加一個(gè)按鈕,樓主使用的是替換到系統(tǒng)自帶的tabBar 然后進(jìn)行布局
- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
        
        //創(chuàng)建一個(gè)按鈕
        UIButton *publishBtn = [[UIButton alloc]init];
        [publishBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
        [publishBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateSelected];
        
        [publishBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
        [publishBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateSelected];
        [publishBtn addTarget:self action:@selector(clickPublish) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:publishBtn];
        self.publishBtn = publishBtn;
    }
    
    return self;
}

- (void)clickPublish {

    NSLog(@"%s",__func__);
    
    //點(diǎn)擊按鈕讓tabbarController成為代碼彈出控制器
//    if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPublish:)]) {
//        
//        [self.tabBarDelegate tabBarDidClickPublish:self];
//    }
    
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    WKPublishViewController *publishVc = [[WKPublishViewController alloc]init];
    WKNavigationController *nav = [[WKNavigationController alloc]initWithRootViewController:publishVc];
    [window.rootViewController presentViewController:nav animated:YES completion:nil];
    
}

- (void)layoutSubviews {

    [super layoutSubviews];

    //設(shè)置加號(hào)按鈕frame
    self.publishBtn.size = self.publishBtn.currentBackgroundImage.size;
    self.publishBtn.center = CGPointMake(self.width * 0.5, self.height * 0.5);
    
    NSInteger index = 0;
    
    for (UIView *tabBarItem in self.subviews) {
        
        //如果子控件不是UITabBarButton  讓循環(huán)繼續(xù)下去
        if (![tabBarItem isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue;
        
            CGFloat tabBarY = 0;
            CGFloat tabBarW = self.width / 5;
            CGFloat tabBarH = self.height;
            CGFloat tabBarX;
            if (index >= 2) {
                tabBarX = (index + 1) * tabBarW;
            }else {
                tabBarX = index * tabBarW;
            }
            
            tabBarItem.frame = CGRectMake(tabBarX, tabBarY, tabBarW, tabBarH);
        
        index ++ ;
        
    }
    
}



其他知識(shí)點(diǎn)補(bǔ)充:

四個(gè)容易混淆的屬性:
1. textAligment : 文字的水平方向的對(duì)齊方式
1> 取值
NSTextAlignmentLeft      = 0,    // 左對(duì)齊
NSTextAlignmentCenter    = 1,    // 居中對(duì)齊
NSTextAlignmentRight    = 2,    // 右對(duì)齊

2> 哪些控件有這個(gè)屬性 : 一般能夠顯示文字的控件都有這個(gè)屬性
* UITextField
* UILabel
* UITextView

2. contentVerticalAlignment : 內(nèi)容的垂直方向的對(duì)齊方式
1> 取值
UIControlContentVerticalAlignmentCenter  = 0, // 居中對(duì)齊
UIControlContentVerticalAlignmentTop     = 1, // 頂部對(duì)齊
UIControlContentVerticalAlignmentBottom  = 2, // 底部對(duì)齊

2> 哪些控件有這個(gè)屬性 : 繼承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...

3. contentHorizontalAlignment : 內(nèi)容的水平方向的對(duì)齊方式
1> 取值
UIControlContentHorizontalAlignmentCenter = 0, // 居中對(duì)齊
UIControlContentHorizontalAlignmentLeft   = 1, // 左對(duì)齊
UIControlContentHorizontalAlignmentRight  = 2, // 右對(duì)齊

2> 哪些控件有這個(gè)屬性 : 繼承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...

4. contentMode : 內(nèi)容模式(控制內(nèi)容的對(duì)齊方式), 一般對(duì)UIImageView很有用
1> 取值
/**
 規(guī)律:
 1.Scale : 圖片會(huì)拉伸
 2.Aspect : 圖片會(huì)保持原來(lái)的寬高比
 */
// 前3個(gè)情況, 圖片都會(huì)拉伸
// (默認(rèn))拉伸圖片至填充整個(gè)UIImageView(圖片的顯示尺寸會(huì)跟UIImageView的尺寸一樣)
UIViewContentModeScaleToFill,
// 按照?qǐng)D片原來(lái)的寬高比進(jìn)行伸縮, 伸縮至適應(yīng)整個(gè)UIImageView(圖片的內(nèi)容不能超出UIImageView的尺寸范圍)
UIViewContentModeScaleAspectFit,
// 按照?qǐng)D片原來(lái)的寬高比進(jìn)行伸縮, 伸縮至 圖片的寬度和UIImageView的寬度一樣 或者 圖片的高度和UIImageView的高度一樣
UIViewContentModeScaleAspectFill,

// 后面的所有情況, 都會(huì)按照?qǐng)D片的原來(lái)尺寸顯示, 不會(huì)進(jìn)行拉伸
UIViewContentModeRedraw,  // 當(dāng)控件的尺寸改變了, 就會(huì)重繪一次(重新調(diào)用setNeedsDisplay, 調(diào)用drawRect:)
UIViewContentModeCenter,
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,

2> 哪些控件有這個(gè)屬性 : 所有UI控件都有

5. 如果有多個(gè)屬性的作用沖突了, 只有1個(gè)屬性有效(就近原則)


一、UINavigationItem
1> 獲得方式
self.navigationItem // self是指控制器

2> 作用
可以用來(lái)設(shè)置當(dāng)前控制器頂部導(dǎo)航欄的內(nèi)容
// 設(shè)置導(dǎo)航欄中間的內(nèi)容
self.navigationItem.title
self.navigationItem.titleView

二、UIBarButtonItem
1> 用在什么地方
// 設(shè)置導(dǎo)航欄左上角的內(nèi)容
self.navigationItem.leftBarButtonItem
// 設(shè)置導(dǎo)航欄右上角的內(nèi)容
self.navigationItem.rightBarButtonItem

2> 作用
相當(dāng)于一個(gè)按鈕

三、UITabBarItem
1> 獲得方式
self.tabBarItem // self是指控制器

2> 作用
可以用來(lái)設(shè)置當(dāng)前控制器對(duì)應(yīng)的選項(xiàng)卡標(biāo)簽的內(nèi)容
// 標(biāo)簽的標(biāo)題
self.tabBarItem.title
// 標(biāo)簽的圖標(biāo)
self.tabBarItem.image
// 標(biāo)簽的選中圖標(biāo)
self.tabBarItem.selectdImage

四、UINavigationBar
1. 導(dǎo)航控制器頂部的欄(UI控件)
2. UINavigationBar上面顯示什么內(nèi)容, 取決于當(dāng)前控制器的navigationItem屬性
3. UINavigationBar是view, navigationItem是model
4. 由navigationItem給UINavigationBar提供顯示的數(shù)據(jù)

五、UITabBar
1. UITabBarController底部的選項(xiàng)卡條

六、UITabBarButton
1. UITabBar底部的每一個(gè)標(biāo)簽
2. 每一個(gè)UITabBarButton里面顯示什么內(nèi)容,取決于當(dāng)前控制器的tabBarItem屬性
3. UITabBarButton是view, tabBarItem是model
4. 由tabBarItem給UITabBarButton提供顯示的數(shù)據(jù)
  • 由于今天的內(nèi)容也很簡(jiǎn)單大家有疑問(wèn)的可以查看源碼,地址:https://github.com/aryehToDog/WKWeibo

  • 還有不同的問(wèn)題,可以在下方提問(wèn).每天的代碼我都會(huì)選取重要的地方進(jìn)行講解.謝謝大家

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,950評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,197評(píng)論 4 61
  • 近期酷愛(ài)看書,也特別想寫讀后感。寫讀后感無(wú)非是想給自己多加深點(diǎn)印象,表明自己看過(guò)這本書,并且從這本書里獲得了一些感...
    和奇谷樸閱讀 1,380評(píng)論 4 12
  • 閩江,繞開(kāi)北江濱的一角沿西而去 過(guò)洪山橋底時(shí),寂靜得恍如隔世 有多少事在這里一了百了 有多少人在這里百無(wú)聊賴 你說(shuō)...
    情島漁夫閱讀 318評(píng)論 1 3

友情鏈接更多精彩內(nèi)容