Recently, there is a demand in the company’s project: basically copy of wechat – ME – album. There are different display styles according to different contents (such as: pure text, pure picture, text + picture, text + link, etc.). I will not write detailed code here. If you have similar requirements, you can customize different cells according to your own requirements to meet them. The customized cell in this Demo is self-adaptive.

Wechat – ME – album:

Feel you need to understand the meaning of the contentOffset property of the sliding view. If you are not sure about it, look at the diagrams for contentSize, contentOffset, and contentInset.

Use lazy loading to create controls

  • I’m going to create a new project, and I’m going to create a tableView, which is probably one of the most commonly used views, and I’m going to use a Group style.
- (UITableView *)tableView
{
    if(! _tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; _tableView.backgroundColor = [UIColor whiteColor]; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.delegate = self; _tableView.dataSource = self; _tableView.estimatedRowHeight = 100; _tableView.rowHeight = UITableViewAutomaticDimension; }return _tableView;
}
Copy the code

The cell ADAPTS to the height, which requires the following code: The number whose height is greater than 0 in principle can be estimated; The second sentence can be written or not written, but the individual used to add.

_tableView.estimatedRowHeight = 100;
_tableView.rowHeight = UITableViewAutomaticDimension;
Copy the code
  • The navigation bar Settings in the project are different, the way to add a sliding series of controls is also different, you can understand this a little bit; By default, the navigation bar is transparent, and the first sliding series view added to the controller view will automatically offset its display by 64 pixels, i.e., contentInset is (64,0,0,0). Generally are where the controller I cancel automatic migration properties: will automaticallyAdjustsScrollViewInsets attribute is set to NO (false).
self.automaticallyAdjustsScrollViewInsets = NO;
Copy the code
  • Add tableView to controller view
[self.view addSubview:self.tableView]; [_tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.and.trailing.equalTo(@0);  make.top.equalTo(self.mas_topLayoutGuide); make.bottom.equalTo(self.mas_bottomLayoutGuideTop); }];Copy the code
  • TableView proxy method: Note that the height of the header and footer section of the tableView must not be 0, otherwise the default height will be displayed. The first section should not have a header as required.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.dataArray.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[self.dataArray objectAtIndex:section] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *iden = @"CCPhotoListCell";
    CCPhotoListCell *cell = [tableView dequeueReusableCellWithIdentifier:iden];
    if(! cell) { cell = [[CCPhotoListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.model = self.dataArray[indexPath.section][indexPath.row];return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"-click --%ld--%ld", indexPath.section, indexPath.row);
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return 0.01;
    }
    return 25;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        
        return nil;
    }
    
    CCPhotoListModel *model = (CCPhotoListModel *)[self.dataArray[section] firstObject];
    
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:[model.time longValue]/1000];
    NSDateFormatter *form = [[NSDateFormatter alloc] init];
    [form setDateFormat:@"yyyy"];
    NSString *dateStr = [form stringFromDate:date];
    
    UIView *headView = [[UIView alloc] init];
    headView.backgroundColor = [UIColor colorWithHex:0xf5f7fa];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, 100, 25)];
    label.textColor = [UIColor colorWithHex:0x434A54];
    label.font = [UIFont boldSystemFontOfSize:13];
    label.text = dateStr;
    [headView addSubview:label];
    
    return headView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if (section == self.dataArray.count - 1) {
        return 0.01;
    }
    return 10;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    if (section == self.dataArray.count - 1) {
        return nil;
    }
    UIView *footView = [[UIView alloc] init];
    footView.backgroundColor = [UIColor colorWithHex:0xf5f7fa];
    return footView;
}
Copy the code
  • The code for custom cell is not posted. This can be customized according to their own needs.

  • Display and switch the year of the current content based on what is displayed: Obviously, you need to figure out how to calculate the year of the current content and change the value of the top year label as you slide.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@"contentOffset: %.2f", scrollView.contentOffset.y);
    NSArray *array = [self.tableView indexPathsForVisibleRows];
    NSIndexPath *indexPath = [array firstObject];
    CGRect rectInTableView = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]];
    CGRect rect = [self.tableView convertRect:rectInTableView toView:self.view];
    
    NSLog(@"%.2f", rect.origin.y);
    if (rect.origin.y <= (64 + 25)) {
        
        CCPhotoListModel *model = (CCPhotoListModel *)[self.dataArray[indexPath.section] firstObject];
        
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:[model.time longValue]/1000];
        NSDateFormatter *form = [[NSDateFormatter alloc] init];
        [form setDateFormat:@"yyyy"];
        NSString *dateStr = [form stringFromDate:date];
        self.timeLabel.text = [NSString stringWithFormat:@In "% @", dateStr];
    }
    
    if(scrollView. ContentOffset. Y > 0) {/ / show/self. View addSubview: self. DisplayTimeView; [self.displayTimeView addSubview:self.timeLabel]; self.displayTimeView.hidden = NO; self.timeLabel.hidden = NO; }else{/ / hide self. DisplayTimeView. Hidden = YES; self.timeLabel.hidden = YES; }}Copy the code
  • If (rect.origin. Y <= (64 + 25)) {}, you should change the threshold value according to your project. For example, if you place a scrollView on self.view, set the contentSize to twice the width of the screen, and place two TableViews on the scrollView, the threshold should be 25 instead of 25 + 64.

  • There are two things you need to know

    • Gets the data in the first row of the tableView displayed on the phone

      NSArray *array = [self.tableView visibleCells]; UITableViewCell *cell = [array firstObject]; Or NSArray * Array = [self.tableView indexPathsForVisibleRows]; NSIndexPath *indexPath = [array firstObject];Copy the code
    - get tableviewCell coordinate values in the current screen ` ` ` CGRect rectInTableView = [tableView rectForRowAtIndexPath: indexPath]; CGRect rect = [tableView convertRect:rectInTableView toView:[tableView superview]]; ` ` `Copy the code

In this Demo, [tableView superview] is the controller view, i.e. Self. view.

Effect:

The Demo address