[ios]自訂UI

來源:互聯網
上載者:User

標籤:

參考:http://blog.sina.com.cn/s/blog_7b9d64af0101edqf.html

回憶一下,這麼個情境。我們在一個介面上,要排列多個相同的元素。你馬上就可以想到:1.如果要用按鈕,可以使用來UIButton布局。如: 

 

- (void) showSectionListbyCount:(float)totalCount everyColCount:(float)paramColCount{

 

    

    int curNum=1;

    

    int TotalRow= ceilf(totalCount/paramColCount);// 總行數

    

    for (int curRow=0; curRow

    

        for (int curCol=0; curCol// 列數

            

            if (totalCount

                return;

            }

            

            UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];

            [btn setFrame:CGRectMake(10+(67+10)*curCol, (30+10)*curRow, 67, 30)];

            

            [btn setTitle:[NSString stringWithFormat:@"%d",curNum]forState:UIControlStateNormal];

            [btn setBackgroundImage:[UIImage imageNamed:@"btn_tv_n"]forState:UIControlStateNormal];

            [btn setBackgroundImage:[UIImage imageNamed:@"btn_tv_h"]forState:UIControlStateHighlighted];

            [btn setTitleColor:[UIColor blackColor]forState:UIControlStateNormal];

            [btn setTitleColor:[UIColor whiteColor]forState:UIControlStateHighlighted];

            [btn addTarget:self action:@selector(ClickControlAction:)forControlEvents:UIControlEventTouchUpInside];

            

            [btn setTag:curNum];

            

            [self.view addSubview:btn];

 

            curNum++;

 

            

        }

        

    }

 

}

 

如果,我們想用表格,那麼每個元素可以使用UITableViewCell來定義相近的項。

 

很簡單是吧,因為,xCode,為我們提供了這些UI控制項供我們使用!所以,我們只需要用!

 

那麼,今天的問題也就來了!如果,我想搞一個能夠滿足自己的一些UI元素。別急,也就是這樣:

比如,我要搞這麼一個介面!

 



我想,首先可以肯定,蘋果不可能為我量身定製了這麼一個控制項。並且,如果,我用蘋果的預設控制項來寫,那麼我肯定會崩潰的。。

 

也就是說,我們將每一項,寫成單獨的一個UI控制項。那麼,可以根據資料進行填充!那就酷斃了!

 

繞了,一大圈,也就是要引用出來今天要學習的,東西!

 

自訂UI!!!

 

說起來,很牛X。其實很簡單,說白了,就是子類化(重寫)UIView。

 

我們常常重寫,UIButton,UIImageView,UITableView 等等。因為,可能我們用到的跟這些已有控制項很相似,稍微修改一些就能夠滿足我們。

 

但是,出入大的時候,我們就不能簡單的繼承於一個已有控制項了!

那就是完全重寫!就是子類化UIView

 

開始動手吧!!!

 

1.定義一UIView個的子類。

這個不解釋!

 

2.重寫drawRect方法。或者重寫layoutSubviews方法、

 

1. drawRect方法:

 

 

 

- (void)drawRect:(CGRect)rect

{

    // Drawing code

    for (int i=0; i<<span style="color: #2f2fd0">10; i++) {

        UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];

        [btn setFrame:CGRectMake(10, 10+i*40, 67, 30)];

        [btn setBackgroundImage:[UIImage imageNamed:@"btn_n"] forState:UIControlStateNormal];

        [btn setBackgroundImage:[UIImage imageNamed:@"btn_h"] forState:UIControlStateHighlighted];

        [btn addTarget:self action:@selector(ClickControlAction:)forControlEvents:UIControlEventTouchUpInside];

        [btn setTag:i];

        

        [self addSubview:btn];

    }

    

}

 

2. layoutSubviews 方法

 

 

- (void)layoutSubviews{

    

    [super layoutSubviews];

    

    [self setBackgroundColor:[UIColor clearColor]];

 

    [_imgPic setFrame:CGRectMake(7, 6, 86, 108)];

    [_imgPic setImage:[UIImage imageNamed:[self.dictData objectForKey:@"img_content"]]];

    [_imgPic.layer setShouldRasterize:NO];

    [_imgPic.layer setBorderColor: [[UIColor whiteColor] CGColor]];

    [_imgPic.layer setBorderWidth: 1.0];

    [[_imgPic layer] setShadowRadius:2];

    [[_imgPic layer] setShadowOpacity:1];

    [[_imgPic layer] setShadowColor:[UIColor blackColor].CGColor];

    [[_imgPic layer] setShadowOffset:CGSizeMake(0, 1)];

    [self addSubview:self.imgPic];

    

 

}

 

可見,這兩種方法都可以的。具體的區別,就是drawRect方法和layoutSubviews方法之間的區別了。

 

但是,經過測試,我發現,應該使用drawRect方法,來完成介面的繪製。因為,如果我們使用的是layoutSubviews方法,那麼每一次改變frame的時候,layoutSubviews都將重新執行。顯然不科學。

 

在網上,我看到,大部分例子使用的是drawRect方法,來重繪介面。(繪製介面)

我使用了layoutSubviews方法。在frame改變時,會自動調用。(重新導向子視圖)

根據需要選擇使用哪一種方法!

 

關於兩種方法,在網上搜了一下,總結如下:

 

 

layoutSubviews在以下情況下會被調用:

 

1、init初始化不會觸發layoutSubviews。

2、addSubview會觸發layoutSubviews。

3、設定view的Frame會觸發layoutSubviews,當然前提是frame的值設定前後發生了變化。

4、滾動一個UIScrollView會觸發layoutSubviews。

5、旋轉Screen會觸發父UIView上的layoutSubviews事件。

6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件。

7、直接調用setLayoutSubviews。

 

drawRect在以下情況下會被調用:

 

1、如果在UIView初始化時沒有設定rect大小,將直接導致drawRect不被自動調用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 兩方法之後掉用的.所以不用擔心在 控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設定一些值給View(如果這些View draw的時候需要用到某些變數 值).

2、該方法在調用sizeToFit後被調用,所以可以先調用sizeToFit計算出size。然後系統自動調用drawRect:方法。

3、通過設定contentMode屬性值為UIViewContentModeRedraw。那麼將在每次設定或更改frame的時候自動調用drawRect:。

4、直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,但是有個前提條件是rect不能為0。

以上1,2推薦;而3,4不提倡

 

drawRect方法使用注意點:

 

1、 若使用UIView繪圖,只能在drawRect:方法中擷取相應的contextRef並繪圖。如果在其他方法中擷取將擷取到一個invalidate 的ref並且不能用於畫圖。drawRect:方法不能手動顯示調用,必須通過調用setNeedsDisplay 或 者 setNeedsDisplayInRect,讓系統自動調該方法。

2、若使用calayer繪圖,只能在drawInContext: 中(類似於drawRect)繪製,或者在delegate中的相應方法繪製。同樣也是調用setNeedDisplay等間接調用以上方法

3、若要即時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay即時重新整理螢幕

 

 

3.自訂UIView的初始化方法。

 

我們常常在UIViewController中,看到initWithNibName方法:

 

 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // coding

    }

    return self;

}

 

這是xCode給我們定義好的初始化方法。

 

既然,我們要自訂UIView,那麼最好,根據自己的商務邏輯,來完成子類化UIView的初始化方法:

 

 

#pragma mark - Initialization 根據商務邏輯,傳入資料,初始化自己

 

- (id)initItemWithFram:(CGRect)frame andData:(NSMutableDictionary *)paramData{

    

    self = [super initWithFrame:frame];

    if (self) {

        // Initialization code

        _dictData=[[NSMutableDictionary alloc] init];

        _imgPic=[[UIImageView alloc] init];

        _imgCover=[[UIImageView alloc] init];

        _btnClick=[[UIButton alloc] init];

        _btnDel=[[UIButton alloc] init];

        _lblTips=[[UILabel alloc] init];

        _lblName=[[UILabel alloc] init];

        

    }

    self.dictData=paramData;

    return self;

    

    

}

 

+ (id) initItemWithFrame:(CGRect)frame andData:(NSMutableDictionary *)paramData{

 

    WTVTVCollectionItem *tmpInstance=[[WTVTVCollectionItem alloc] initItemWithFram:frameandData:paramData];

    return tmpInstance;

}

 

這樣,就可以初始化:

 

 

NSMutableArray *items = [NSMutableArray array];

    

    [items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];

    [items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];

    [items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];

 

4.為UIView加入一些動畫

 

動畫是UI操作的靈魂!給予動畫效果,就看上去有神了。

 

添加動畫,一般也用2種方法:

 

1.重寫UIView的方法,在調用時,進行動畫操作。

 

 

# pragma mark - 重寫父類的removeFromSuperview方法,在刪除時,使用相應的動畫效果

 

- (void) removeFromSuperview {

    

    [UIView animateWithDuration:0.2 animations:^{

        self.alpha = 0.0;

        [self setFrame:CGRectMake(self.frame.origin.x+50, self.frame.origin.y+50, 0, 0)];

        [_btnDel setFrame:CGRectMake(0, 0, 0, 0)];

    }completion:^(BOOL finished) {

        [super removeFromSuperview];

    }];

}

 

2.直接在UIView元素上,進行動畫對象的添加

 

 

 

- (void) enableEditing {

    

    if (self.isInEditingMode == YES)

        return;

    

    // 設定為編輯狀態

    self.isInEditingMode = YES;

    [_btnDel setHidden:NO];

    

    // 開始晃動動畫

    CATransform3D transform;

    // 擷取0到x-1之間的整數

    if (arc4random() % 2 == 1)

        transform = CATransform3DMakeRotation(-0.08, 0, 0, 1.0);

    else

        transform = CATransform3DMakeRotation(0.08, 0, 0, 1.0);

    

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];

    animation.toValue = [NSValue valueWithCATransform3D:transform];

    animation.autoreverses = YES;

    animation.duration = 0.1;

    animation.repeatCount = 10000;

    animation.delegate = self;

    [[self layer] addAnimation:animation forKey:@"wiggleAnimation"];

 

    [(WTVTVSprintBoard*)self.delegate enableEditingMode];

    

}

 

5.子類化UIView的互動

 

如何將操作鏈結接起來!?就是說,在控制項外,對我們自訂的控制項進行操作?!

 

也有2種方法:

 

1.訊息

2.代理

 

總結:

 

我想,我過多的將思路就可以了,因為業務需求不同,控制項的自訂需求也不同,所以,不能用具體來固定!但是,思路是想通的,知道了原理,我們就可以發揮我們的聰明智慧,創造出千變萬化的控制項來!

 

 

希望對你有所協助!!!

[ios]自訂UI

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.