標籤:
1:initWithFrame方法的理解
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會觸發layoutSubviewsc、設定view的Frame會觸發layoutSubviews,當然前提是frame的值設定前後發生了變化d、滾動一個UIScrollView會觸發layoutSubviewse、旋轉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:一個選項卡的封裝
.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中對它進行轉換賦值;
iOS開發基礎知識--片段18