At the beginning

  • This is a sub-chapter. For the whole article, see the Learning Diary of Zero-based iOS development

UITableViewController

The actual use

  • Weibo and Twitter interface
  • Wechat, QQ friends interface, chat interface
  • News interface
  • As long as the interface needs to list the content, and each piece of content needs roughly the same data, can be used

Basic usage

  • UITableViewControllerData is also loaded throughUITableViewDataSourceIs implemented by the proxy method
  • Heads and tails can also return
/ / set number - (NSInteger) numberOfSectionsInTableView tableView: (UITableView *) {return 2; } // row number - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return 5; } //cell style - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; cell.textLabel.text = @"test"; return cell; } // header - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {return [NSString stringWithFormat:@"Header%ld", section]; } // tail - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {return [NSString stringWithFormat:@"Footer%ld", section]; }Copy the code

UITableView

The form style

UITableViewStylePlain / / header and footer is suspended UITableViewStyleGrouped / / common, header and footer can scroll UITableViewStyleInsetGrouped / / inline style with interfaceCopy the code
  • Set up theUITableViewControllerThe form style of
- (instancetype)initWithStyle:(UITableViewStyle)style {
    return [super initWithStyle:UITableViewStyleInsetGrouped];
}
Copy the code
  • Add on the interfaceUITableView
self.view = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStyleGrouped];
Copy the code

Some of the Settings

  • Set the dividing line
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine,
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
Copy the code
  • Dividing line color
self.tableView.separatorColor = [UIColor redColor];
Copy the code
  • Color rendering
self.tableView.tintColor = [UIColor orangeColor];
Copy the code

Data refresh

  • When it comes to updating data in a form, a data refresh is required
// Refresh all [self.tableView reloadData]; // Refresh a set of NSIndexSet *idxSet = [NSIndexSet indexSetWithIndex:1]; [self.tableView reloadSections:idxSet withRowAnimation:UITableViewRowAnimationFade]; // Refresh a row NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:1]; [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];Copy the code

UITableViewCell

  • In actual development,UITableViewCellGenerally custom, but not high requirements will choose to use the systemcelltype
UITableViewCellStyleDefault / / picture + captions UITableViewCellStyleValue1 / / picture + + comments UITableViewCellStyleValue2 / / title + left and right UITableViewCellStyleSubtitle / / picture + title + annotationCopy the code

Basic setup

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
cell.textLabel.text = @"test";
cell.imageView.image = [UIImage imageNamed:@"dv_icon1"];
cell.detailTextLabel.text = @"detail";
Copy the code

Some of the Settings

  • indicator
cell.accessoryType = UITableViewCellAccessoryDetailButton;
UITableViewCellAccessoryNone
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark
UITableViewCellAccessoryDetailButton
Copy the code
  • Blue and gray are set in the same style as default. What is the reason
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray,
UITableViewCellSelectionStyleDefault
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Copy the code

highly

  • In actual development, the height of each cell is different. You can calculate the height attribute in a customized model
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
}
Copy the code

Functions of application scenarios

rolling

  • Scroll to a specified position, for example, click the QQ or wechat input box, and the interface automatically rolls to the last message. There are four places to scroll, but I tried, what difference does it make
[the self tableView scrollToRowAtIndexPath: idxPath/group/rolling column and atScrollPosition: UITableViewScrollPositionTop / / the position of the scroll animated:YES];Copy the code

UIRefreshControl implements drop-down refresh

  • throughrefreshControl, it isUITableViewControllerBuilt-in refresh control
  • As long as it’s set uprefreshControl, the control will always exist
UIRefreshControl *rc = [UIRefreshControl new]; / / specified method [rc addTarget: self action: @ the selector (loadData) forControlEvents: UIControlEventValueChanged]; // Chrysanthemum color rc.tintColor = [UIColor orangeColor]; / / custom text NSDictionary * attrDic = @ {NSFontAttributeName: [UIFont systemFontOfSize: 20], NSForegroundColorAttributeName: [UIColor redColor], NSBackgroundColorAttributeName : [UIColor blueColor] }; Rc. AttributedTitle = [[NSAttributedString alloc] initWithString:@" Refreshing "Attributes :attrDic]; self.refreshControl = rc; Self. refreshControl beginRefreshing [self.refreshControl beginRefreshing]; [self.refreshControl endRefreshing];Copy the code
  • Due to theUIRefreshControlIt is not called automatically on refreshbeginRefreshing, so call it manually, and override itbeginRefreshingandendRefreshing, to achieve custom animation effect, the original chrysanthemum cover
  • The customUIRefreshControlThe following example is simply usedUIViewShows animated changes and usesKVOMethod call ofbeginRefreshing
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { if (self.isRefreshing) { [UIView animateWithDuration:1 animations:^{ self.v1.alpha = Self.v2. alpha = 1;}]; }} // init function - (instanceType)init {self = [super init]; if (self) { [self setupUI]; //kvo checks whether to drag [self addObserver:self forKeyPath:@"frame" options:0 context:nil]; } return self; } - (void)dealloc {// remove kvo [self removeObserver:self forKeyPath:@"frame"]; } - (void)beginRefreshing { [super beginRefreshing]; NSLog(@"CustomRefreshControl - beginRefreshing"); [UIView animateWithDuration:1 animations:^{self.v1.alpha = 0.5; self.v2.alpha = 1;}]; [UIView animateWithDuration:1 animations:^{self.v1.alpha = 0.5; self.v2.alpha = 1;}]; } - (void)endRefreshing { [super endRefreshing]; NSLog(@"CustomRefreshControl - endRefreshing"); [UIView animateWithDuration:1 animations:^{ self.v1.alpha = 1; self.v2.alpha = 0; }]; } - (void)setupUI { UIView *v1 = [UIView new]; v1.frame = CGRectMake(50, 0, self.bounds.size.width, self.bounds.size.height); v1.backgroundColor = [UIColor redColor]; UIView *v2 = [UIView new]; v2.frame = CGRectMake(50, 0, self.bounds.size.width, self.bounds.size.height); v2.backgroundColor = [UIColor blueColor]; v2.alpha = 0; self.tintColor = [UIColor clearColor]; [self addSubview:v2]; [self addSubview:v1]; self.v1 = v1; self.v2 = v2; }Copy the code

Pull down refresh via headerView

  • However, withUIRefreshControl, there is a problem, during the actual refresh, the refreshed layer will appear inUITableViewThe top is not very beautiful, so for no needheaderViewIn the form, I chose to customizeUIViewTo borrowheaderViewTo implement a drop-down refresh
  • RefreshViewWith the customUIRefreshControlSimilarly, inbeginRefreshingandendRefreshingWrite the corresponding animation, when should be called, not to repeat here
  • ViewDidLoad base setup
self.refreshView = [[RefreshView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)]; // Get status bar height CGFloat statusHeight = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager.statusBarFrame.size.height; / / set the tableView upward displacement of the self. The tableView. ContentInset = UIEdgeInsetsMake (- 50 - statusHeight, 0, 0, 0). self.tableView.tableHeaderView = self.refreshView; self.refreshFlag = NO;Copy the code
  • Call when release, data refresh when pull down to a certain state
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { NSLog(@"%f", scrollView.contentOffset.y); If (velocity. Y < 0 & & self. The tableView. ContentOffset. Y < - self. TableView. TableHeaderView. Bounds. The size, height) {/ / calls to start fresh [self.refreshView beginRefreshing]; self.refreshFlag = YES; / / keep the interface position, is the self refresh head. The tableView. ContentInset = UIEdgeInsetsMake (0, 0, 0, 0); }}Copy the code
  • Called at the end of the scroll, with a delay and flag bit to simulate the completion of the data acquisition
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { CGFloat statusHeight = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager.statusBarFrame.size.height; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{if(self.refreshFlag) {[UIView animateWithDuration:0.5 animations:^{ And restore the interface position [self refreshView endRefreshing]; self. RefreshFlag = NO; self. TableView. ContentInset = UIEdgeInsetsMake(-50-statusHeight, 0, 0, 0); }]; }}); }Copy the code

The pull to refresh

  • The pull to refresh
  • Often pull refresh is not particularly fancy, with the system can own
Self. footerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; self.tableView.tableFooterView = self.footerView; // Start refreshing [self.footerView startAnimating]; // End refresh [self.footerView stopAnimating];Copy the code

Jump or execute method

  • Select a line to handle, such as jump to a different interface, the following, according to the text, jump to the interface, willNSStringInto a class
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *targetVC = cell.textLabel.text;
    Class class = NSClassFromString(targetVC);
    UIViewController *vc = [class new];
    [self presentViewController:vc animated:YES completion:nil];
}
Copy the code
  • I’ll write it by the wayNSStringConvert to the method name
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *targetFunc = cell.textLabel.text;
SEL funcName = NSSelectorFromString(targetFunc);
[self performSelector:funcName];
Copy the code
  • With parameters, if more parameters, you can use dictionary pass
// Call [self performSelector:funcName withObject:@"name" withObject:@18]; // function - (void)testViewController:(NSString *)name andAge:(NSNumber *)age {NSLog(@"testViewController %@ %d", name, [age intValue]); } / / the contents of the cell cell. TextLabel. Text = @ "testViewController: andAge:";Copy the code