iOS學習3_UI開發之純代碼/storyboard/xib

因爲作android開發時間比較長,按照android的經驗,通常開發界面都是使用xml來寫佈局文件的,不多會徹底使用代碼來寫佈局,最近剛學iOS,發現好多都是直接使用代碼來寫佈局的。看視頻學習恰好看到這個不錯的小項目,所以作了一點小小的整理。android

要實現的效果以下,點擊加號添加一條,點擊回收投標刪除最下面一條,點擊刪除會刪除當前的一條。點擊頭片會更改中間的文字。刪除/添加會伴隨動畫。dom


1.使用純代碼來寫佈局


點擊添加按鈕ide

- (IBAction)add:(UIBarButtonItem *)sender{
    UIView * v = [self getRowView];
    UIView * lastView = [[self.view subviews] lastObject];
    NSLog(@"%@",lastView);
    CGFloat rowY = lastView.frame.origin.y + lastView.frame.size.height + 1;
    v.frame = CGRectMake(_screenWidth, rowY, _screenWidth, KHeight);
    v.alpha = 0;
    [self.view addSubview:v];
    
    [UIView animateWithDuration:0.5 animations:^{
        v.alpha = 1;
        v.frame = CGRectMake(0, rowY, _screenWidth, KHeight);
    }];
    [self.removeItem setEnabled:true];
}

點擊回收最後面一條按鈕
函數

- (IBAction)remove:(UIBarButtonItem *)sender
{
    UIView * lastView = [[self.view subviews] lastObject];

    [UIView animateWithDuration:0.5 animations:^{
        CGRect tempF = lastView.frame;
        tempF.origin.x = _screenWidth;
        lastView.frame = tempF;
        lastView.alpha = 0;
    } completion:^(BOOL finished) {
        [lastView removeFromSuperview];
        [self.removeItem setEnabled:self.view.subviews.count > 1];
}];
}
getRowView函數是獲得一行item的佈局View

- (UIView *) getRowView
{
UIView * view = [[UIView alloc]init];
    view.bounds = CGRectMake(0, 0, self.view.frame.size.width, KHeight);
    [view setBackgroundColor:[UIColor grayColor]];
    
    // 建立文字
    UILabel * label = [[UILabel alloc]init];
    label.frame = CGRectMake(0, 0, self.view.frame.size.width, KHeight);
    label.text =_allNames[arc4random_uniform(_allNames.count)];
    label.textColor = [UIColor blackColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.tag = 10;
    [view addSubview:label];
    
    // 建立頭像
    UIButton * icon = [[UIButton alloc]init];
    icon.frame = CGRectMake(20, 0, KHeight , KHeight);
    int randomIndex = arc4random_uniform(9);
    NSString *iconName = [NSString stringWithFormat:@"01%d.png", randomIndex];
    // 設置圖片
    [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
    // 添加監聽器
    [icon addTarget:self action:@selector(iconClick:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:icon];
    
    // 建立刪除按鈕
    UIButton * deleteIcon = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [deleteIcon setCenter:CGPointMake(280, KHeight/2)];
    deleteIcon.bounds = CGRectMake(0, 0, 60 , 30);
    [deleteIcon setTitle:@"刪除" forState:UIControlStateNormal];
    [deleteIcon addTarget:self action:@selector(deleteClick:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:deleteIcon];
    return  view;
}
點擊圖片的響應函數

- (void)iconClick:(UIButton *)btn
{
    UILabel * label = (UILabel *)[[btn superview] viewWithTag:10];
    NSString * oriStr = [label text];
    NSString * newStr = [NSString stringWithFormat:@"%@+%@",oriStr,oriStr];
    label.text = newStr;
}
點擊刪除某一項的按鈕

- (void) deleteClick:(UIButton * )btn
{
    [UIView animateWithDuration:0.5 animations:^{
        CGRect tempF = [btn.superview frame];
        tempF.origin.x = _screenWidth;
        btn.superview.frame = tempF;
    } completion:^(BOOL finished) {
        
        // 將下面的全部項向上移動
        int startIndex = [self.view.subviews indexOfObject:btn.superview];
        [btn.superview removeFromSuperview];
        [UIView animateWithDuration:0.5 animations:^{
            for (int i = startIndex; i < self.view.subviews.count; i++) {
                UIView *child = self.view.subviews[i];
                CGRect tempF = child.frame;
                tempF.origin.y -= KHeight + 1;
                child.frame = tempF;
            }
        }];
        
    }];
}
能夠看出來徹底使用代碼來寫佈局很是的麻煩,使用storyboard拖控件能夠經過連線的方式減小代碼量,上面的代碼中,添加一條item的內容很是繁瑣。

2.使用xib來做爲每一個item的加載佈局

好處:不須要本身使用代碼進行這一行的佈局佈局

缺點:存在的問題是還須要經過代碼添加點擊事件。學習


加載xib文件的方式生成每一行的佈局,具體以下
- (UIView *) getRowView
{
    NSArray * views = [[NSBundle mainBundle] loadNibNamed:@"item" owner:nil options:nil];
    UIView * view = views[0];
    
    UIButton * icon = view.subviews[0];
    UILabel * label = view.subviews[1];
    UIButton * deleteIcon = view.subviews[2];
    NSLog(@"%@ + %@ + %@",icon,label,deleteIcon);
    NSString *iconName = [NSString stringWithFormat:@"01%d.png",arc4random_uniform(9)];
    
    [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
    
    label.text = _allNames[arc4random_uniform(_allNames.count)];
    [deleteIcon addTarget:self action:@selector(deleteClick:) forControlEvents:UIControlEventTouchUpInside];
    return  view;
}

3.使用xib和連線

好處:不須要本身添加點擊事件的觸發。指定了FileOwer,FileOwer保證了能夠連線,指定某個xib的FileOwer也就是指定了它的管理類。動畫

缺點:這樣存在的問題是代碼間的耦合性過高,spa

理論上在建立一行時,也就是在getRowView方法裏面,並不須要關注具體的細節,不須要關注他的子控件,最好的狀況就是隻給傳遞咱們須要顯示的數據,剩下的本身不須要處理。而且很差實現代碼的複用。code


注:必須指定File’s Ower 不然沒法連線,而且在使用代碼加載的時候指定該參數。FileOwer並不必定要是這個類,任何一個類都是能夠的。orm

- (UIView *) getRowView
{
    NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"item" owner:self options:nil];
    UIView *view = views[0];
    UIButton * icon = view.subviews[0];
    UILabel * label = view.subviews[1];
    NSString *iconName = [NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)];
    [icon setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
    label.text = _allNames[arc4random_uniform(_allNames.count)];
return view;
}

4.自定義View


注意:這裏不能指定File Owner的屬性,將View的Class屬性設置爲咱們自定義的View便可連線。

MyView中的類方法以下

+ (MyView *) myViewWithIcon:(UIImage *)iconImage andLabel:(NSString *)labelStr
{
    MyView *view = [[NSBundle mainBundle] loadNibNamed:@"item" owner:nil options:nil][0];
    [view.iconBtn setImage:iconImage forState:UIControlStateNormal];
    
    view.label.text = labelStr;

    return view;
}

這樣建立一行View的代碼爲

- (UIView *) getRowView
{
    MyView * view = [MyView myViewWithIcon:[UIImage imageNamed:[NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)]] andLabel:_allNames[arc4random_uniform(_allNames.count)]];
return view;
}

使用MyView來建立一行View時就能夠徹底和其餘的代碼分開,由於處理它的子控件的業務所有由他本身來處理。

以上內容整理自視頻

相關文章
相關標籤/搜索