IOS 3_UI development-pure code/storyboard/xib, 3_uistoryboard
Since android development takes a long time, according to android experience, the development interface generally uses xml to write layout files, and seldom uses code to write the layout. Recently I just learned iOS, I found that many of them use code to write the layout directly. Watching videos and learning is just like seeing this good small project, so I made a little bit of work.
The following figure shows the effect. Click the plus sign to add one, click the recycling bidding to delete the bottom one, and click Delete to delete the current one. Click the header to change the text in the middle. The deletion or addition will be accompanied by an animation.
1. Use pure code to write Layout
Click Add
- (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];}
Click the recycle last button.
- (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];}];}
The getRowView function is used to obtain the Layout View of a row of items.
-(UIView *) getRowView {UIView * view = [[UIView alloc] init]; view. bounds = CGRectMake (0, 0, self. view. frame. size. width, KHeight); [view setBackgroundColor: [UIColor grayColor]; // create text 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]; // create an avatar 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]; // set the image [icon setImage: [UIImage imageNamed: iconName] forState: UIControlStateNormal]; // Add the listener [icon addTarget: self action: @ selector (iconClick :) forControlEvents: UIControlEventTouchUpInside]; [view addSubview: icon]; // create and delete UIButton * deleteIcon = [UIButton buttonWithType: Custom]; [deleteIcon setCenter: CGPointMake (280, KHeight/2)]; deleteIcon. bounds = CGRectMake (0, 0, 60, 30); [deleteIcon setTitle: @ "delete" forState: UIControlStateNormal]; [deleteIcon addTarget: self action: @ selector (deleteClick :) forControlEvents: UIControlEventTouchUpInside]; [view addSubview: deleteIcon]; return view ;}
Response Function for clicking an image
- (void)iconClick:(UIButton *)btn{ UILabel * label = (UILabel *)[[btn superview] viewWithTag:10]; NSString * oriStr = [label text]; NSString * newStr = [NSString stringWithFormat:@"%@+%@",oriStr,oriStr]; label.text = newStr;}
Click "delete ".
-(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) {// move all the following items Up 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 ;}}] ;}] ;}}
It can be seen that it is very troublesome to use code to write the layout. The storyboard Drag Control can reduce the amount of code by connecting lines. In the above Code, it is very cumbersome to add an item.
2. Use xib as the loading layout for each item
Benefit: you do not need to use the code to layout this line.
Disadvantage: you also need to add click events through code.
Load the xib file to generate the layout of each row, as shown below:
- (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. Use xib and link
Benefit: you do not need to add a click event trigger by yourself. The FileOwer is specified, and the FileOwer ensures that the file can be connected. The FileOwer of an xib instance specifies its management class.
Disadvantage: the coupling between codes is too high,
Theoretically, when creating a row, that is, in the getRowView method, you do not need to pay attention to the specific details, and do not need to pay attention to its sub-controls, the best case is to pass the data we need to display, And the rest do not need to be processed. It is difficult to reuse code.
Note: You must specify the File's Ower. Otherwise, the File cannot be connected and this parameter is specified when code is loaded. FileOwer does not necessarily use this class. Any class is acceptable.
- (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. Custom View
Note: The attribute of File Owner cannot be specified here. Set the Class attribute of View to the custom View to connect.
The class methods in MyView are as follows:
+ (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;}
In this way, the code for creating a View row is
- (UIView *) getRowView{ MyView * view = [MyView myViewWithIcon:[UIImage imageNamed:[NSString stringWithFormat:@"01%d.png", arc4random_uniform(9)]] andLabel:_allNames[arc4random_uniform(_allNames.count)]];return view;}
When using MyView to create a View line, it can be completely separated from other code, because the business of its sub-control is handled by itself.
The above content is organized from the video