iOS開發基礎知識--碎片18

 

iOS開發基礎知識--碎片18 

1:initWithFrame方法的理解ios

複製代碼
1. initWithFrame方法是什麼?
initWithFrame方法用來初始化並返回一個新的視圖對象,根據指定的CGRect(尺寸)。
固然,其餘UI對象,也有initWithFrame方法,可是,咱們以UIView爲例,來搞清楚initWithFrame方法。

2.何時用initWithFrame方法?
簡單的說,咱們用編程方式申明,建立UIView對象時,使用initWithFrame方法。
在此,咱們必須搞清楚,兩種方式來進行初始化UIView。
a.使用 Interface Builder 方式。
這種方式,就是使用nib文件。一般咱們說的「拖控件」 的方式。
實際編程中,咱們若是用Interface Builder 方式建立了UIView對象。(也就是,用拖控件的方式)
那麼,initWithFrame方法方法是不會被調用的。由於nib文件已經知道如何初始化該View。(由於,咱們在拖該view的時候,就定義好了長、寬、背景等屬性)。
這時候,會調用initWithCoder方法,咱們能夠用initWithCoder方法來從新定義咱們在nib中已經設置的各項屬性。

b.使用編程方式。
就是咱們聲明一個UIView的子類,進行「手工」編寫代碼的方式。
實際編程中,咱們使用編程方式下,來建立一個UIView或者建立UIView的子類。這時候,將調用initWithFrame方法,來實例化UIView。
特別注意,若是在子類中重載initWithFrame方法,必須先調用父類的initWithFrame方法。在對自定義的UIView子類進行初始化操做。
好比:
- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];// 先調用父類的initWithFrame方法
    if (self) {
        
        // 再自定義該類(UIView子類)的初始化操做。
        _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        [_scrollView setFrame:CGRectMake(0, 0, 320, 480)];
        _scrollView.contentSize = CGSizeMake(320*3, 480);
        
        [self addSubview:_scrollView];
    }
    return self;
}
複製代碼

2:layoutSubviews總結編程

複製代碼
layoutSubviews在如下狀況下會被調用:
a、init初始化不會觸發layoutSubviews
   可是是用initWithFrame 進行初始化時,當rect的值不爲CGRectZero時,也會觸發
b、addSubview會觸發layoutSubviews
c、設置view的Frame會觸發layoutSubviews,固然前提是frame的值設置先後發生了變化
d、滾動一個UIScrollView會觸發layoutSubviews
e、旋轉Screen會觸發父UIView上的layoutSubviews事件
f、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件

layoutSubviews, 當咱們在某個類的內部調整子視圖位置時,須要調用。反過來的意思就是說:若是你想要在外部設置subviews的位置,就不要重寫。layoutSubviews對subviews從新佈局,layoutSubviews方法調用先於drawRect

刷新子對象佈局
-layoutSubviews方法:這個方法,默認沒有作任何事情,須要子類進行重寫
-setNeedsLayout方法: 標記爲須要從新佈局,異步調用layoutIfNeeded刷新佈局,不當即刷新,但layoutSubviews必定會被調用
-layoutIfNeeded方法:若是,有須要刷新的標記,當即調用layoutSubviews進行佈局(若是沒有標記,不會調用layoutSubviews)
若是要當即刷新,要先調用[view setNeedsLayout],把標記設爲須要佈局,而後立刻調用[view layoutIfNeeded],實現佈局
在視圖第一次顯示以前,標記老是「須要刷新」的,能夠直接調用[view layoutIfNeeded]
複製代碼

3:單元行有其它控件時,行選中時關於控件高亮的問題異步

複製代碼
此處是cell中的accessoryView放一UIButton,在行被選中的狀況下,UIButton同時也被高亮處於被選中的壯態,經過下面這樣處理能夠解決問題

@interface UCaiTableViewCell : UITableViewCell

@end

@implementation UCaiTableViewCell

@synthesize piosaDelegate = _piosaDelegate;

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
    [super setHighlighted:highlighted animated:animated];
    
    if (highlighted) {
        [(UIButton *)self.accessoryView setHighlighted:NO];
    }
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
    [super setSelected:selected animated:animated];
    
    if (selected) {
        [(UIButton *)self.accessoryView setHighlighted:NO];
    }
}
複製代碼

4:UIButton高亮效果去除佈局

複製代碼
繼承UIButton而後能夠重寫setHighlighed方法,裏面什麼內容也不寫;

.H文件:

#import <UIKit/UIKit.h>

@interface HWEmotionTabBarButton : UIButton

@end


.M文件:

#import "HWEmotionTabBarButton.h"

@implementation HWEmotionTabBarButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // 設置文字顏色
        [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [self setTitleColor:[UIColor darkGrayColor] forState:UIControlStateDisabled];
        // 設置字體
        self.titleLabel.font = [UIFont systemFontOfSize:13];
    }
    return self;
}

- (void)setHighlighted:(BOOL)highlighted {
    // 按鈕高亮所作的一切操做都不在了
}
@end
複製代碼

5:一個選項卡的封裝post

複製代碼
.H文件內容

#import <UIKit/UIKit.h>

typedef enum {
    HWEmotionTabBarButtonTypeRecent, // 最近
    HWEmotionTabBarButtonTypeDefault, // 默認
    HWEmotionTabBarButtonTypeEmoji, // emoji
    HWEmotionTabBarButtonTypeLxh, // 浪小花
} HWEmotionTabBarButtonType;

@class HWEmotionTabBar;

@protocol HWEmotionTabBarDelegate <NSObject>

@optional
- (void)emotionTabBar:(HWEmotionTabBar *)tabBar didSelectButton:(HWEmotionTabBarButtonType)buttonType;
@end

@interface HWEmotionTabBar : UIView
@property (nonatomic, weak) id<HWEmotionTabBarDelegate> delegate;
@end

注意:這邊主要是要引入@class


.M文件內容:

@interface HWEmotionTabBar()
@property (nonatomic, weak) HWEmotionTabBarButton *selectedBtn;
@end

@implementation HWEmotionTabBar

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupBtn:@"最近" buttonType:HWEmotionTabBarButtonTypeRecent];
        [self setupBtn:@"默認" buttonType:HWEmotionTabBarButtonTypeDefault];
//        [self btnClick:[self setupBtn:@"默認" buttonType:HWEmotionTabBarButtonTypeDefault]];
        [self setupBtn:@"Emoji" buttonType:HWEmotionTabBarButtonTypeEmoji];
        [self setupBtn:@"浪小花" buttonType:HWEmotionTabBarButtonTypeLxh];
    }
    return self;
}

/**
 *  建立一個按鈕
 *
 *  @param title 按鈕文字
 */
- (HWEmotionTabBarButton *)setupBtn:(NSString *)title buttonType:(HWEmotionTabBarButtonType)buttonType
{
    // 建立按鈕
    HWEmotionTabBarButton *btn = [[HWEmotionTabBarButton alloc] init];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
    btn.tag = buttonType;
    [btn setTitle:title forState:UIControlStateNormal];
    [self addSubview:btn];
    
    // 設置背景圖片
    NSString *image = @"compose_emotion_table_mid_normal";
    NSString *selectImage = @"compose_emotion_table_mid_selected";
    if (self.subviews.count == 1) {
        image = @"compose_emotion_table_left_normal";
        selectImage = @"compose_emotion_table_left_selected";
    } else if (self.subviews.count == 4) {
        image = @"compose_emotion_table_right_normal";
        selectImage = @"compose_emotion_table_right_selected";
    }
    
    [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
    [btn setBackgroundImage:[UIImage imageNamed:selectImage] forState:UIControlStateDisabled];
    
    return btn;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // 設置按鈕的frame
    NSUInteger btnCount = self.subviews.count;
    CGFloat btnW = self.width / btnCount;
    CGFloat btnH = self.height;
    for (int i = 0; i<btnCount; i++) {
        HWEmotionTabBarButton *btn = self.subviews[i];
        btn.y = 0;
        btn.width = btnW;
        btn.x = i * btnW;
        btn.height = btnH;
    }
}

- (void)setDelegate:(id<HWEmotionTabBarDelegate>)delegate
{
    _delegate = delegate;
    
    // 選中「默認」按鈕
    [self btnClick:(HWEmotionTabBarButton *)[self viewWithTag:HWEmotionTabBarButtonTypeDefault]];
}

/**
 *  按鈕點擊
 */
- (void)btnClick:(HWEmotionTabBarButton *)btn
{
    //轉換被選中的效果
    self.selectedBtn.enabled = YES;
    btn.enabled = NO;
    self.selectedBtn = btn;
    
    // 通知代理
    if ([self.delegate respondsToSelector:@selector(emotionTabBar:didSelectButton:)]) {
        [self.delegate emotionTabBar:self didSelectButton:btn.tag];
    }
}

@end

注意:當增長完控件後,self.subviews.count這個值就是從1開始,而setDelegate則是爲了用來顯示默認被選中,由於有枚舉因此能夠很準肯定位到想設置默認的那個UIButton,UIControlStateDisabled這個狀態是爲了當被選中後就不能再點擊,配合着enabled設置,代碼中建立的一個屬性用於存放當前被選中的UIButton,在事件btnClick中對它進行轉換賦值;
複製代碼
相關文章
相關標籤/搜索