因爲作android開發時間比較長,按照android的經驗,通常開發界面都是使用xml來寫佈局文件的,不多會徹底使用代碼來寫佈局,最近剛學iOS,發現好多都是直接使用代碼來寫佈局的。看視頻學習恰好看到這個不錯的小項目,所以作了一點小小的整理。android
要實現的效果以下,點擊加號添加一條,點擊回收投標刪除最下面一條,點擊刪除會刪除當前的一條。點擊頭片會更改中間的文字。刪除/添加會伴隨動畫。dom
點擊添加按鈕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的內容很是繁瑣。
好處:不須要本身使用代碼進行這一行的佈局佈局
缺點:存在的問題是還須要經過代碼添加點擊事件。學習
- (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; }
好處:不須要本身添加點擊事件的觸發。指定了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; }
注意:這裏不能指定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時就能夠徹底和其餘的代碼分開,由於處理它的子控件的業務所有由他本身來處理。
以上內容整理自視頻