[iOS] tableView中实现底部button出现时tableView的bottom自动向上偏移

这是我在工程中遇到的一个需求:选择照片以后,按bottomButton进行发送。ide

具体场景:照片存放在tableviewcontroller中,当选择照片以后,自动弹出bottomButton,点击以后发送照片;当取消全部的照片以后该button自动消失。函数

问题:该button会遮挡底部的照片,因此须要实现当底部的button出现时tableView的bottom自动向上偏移的功能。atom

  我用autoLayout和contentOffset来解决这个问题的,在一开始就建立这两个view(tableview 和bottomButton),经过控制NSLayoutConstant的constant来控制该button的出现,省去了hidden = YES/NO;下面经过代码进行分析:orm

- (void)setupUIthree

{ip

  [self createPhotoView];animation

  [self sendButtonView];it

  // auto layoutio

  self.assetsViewController.view.translatesAutoresizingMaskIntoConstraints = NO;table

  self.sendButtonView.translatesAutoresizingMaskIntoConstraints = NO;

  NSDictionary *viewsDict = @{@"assetsView": self.assetsViewController.view,

                             @"sendBtnView": self.sendButtonView};

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[assetsView]-0-|" options:0 metrics:nil views:viewsDict]];

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[sendBtnView]-0-|" options:0 metrics:nil views:viewsDict]];

  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[assetsView]-0-[sendBtnView]-0-|" options:0 metrics:nil views:viewsDict]];

  self.sendBtnHeightLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.sendButtonView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0];

  [self.view addConstraint:self.sendBtnHeightLayoutConstraint];

}

这部分控制了该button的水平和垂直方向,主要是垂直方向的控制。关键是 self.sendBtnHeightLayoutConstraint变量比较巧妙,这是我以前申请的一个属性:

@property (nonatomic, strong) NSLayoutConstraint *sendBtnHeightLayoutConstraint;

而 self.sendBtnHeightLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.sendButtonView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0];实际经过对该变量进行赋值以控制其隐藏或出现,下面会继续分析。

 

接着是显示button的函数:

- (void)updateBottomButton:(NSInteger)selectedItemCount

{

 // use animation 

  [UIView animateWithDuration:0.5f animations:^{

    if (0 >= selectedItemCount) {//hide

      self.sendBtnHeightLayoutConstraint.constant = 0;

      self.tableViewAdjustOffsetY = 0.0;

    } else { //show

      self.sendBtnHeightLayoutConstraint.constant = kHeightForSendButton;

     // three conditions

      BOOL isMoreThanOnePage = self.assetsViewController.tableView.contentSize.height > self.assetsViewController.tableView.frameHeight;

      BOOL isInLastPage = self.assetsViewController.tableView.contentOffset.y > self.assetsViewController.tableView.contentSize.height - self.assetsViewController.tableView.frameHeight;

      BOOL hasAdjustedOffsetY = self.assetsViewController.tableView.contentOffset.y == self.tableViewAdjustOffsetY;

      if (isMoreThanOnePage && isInLastPage && !hasAdjustedOffsetY) {

        self.tableViewAdjustOffsetY = self.assetsViewController.tableView.contentOffset.y + kHeightForSendButton;

        self.assetsViewController.tableView.contentOffset = CGPointMake(self.assetsViewController.tableView.contentOffset.x, self.tableViewAdjustOffsetY);

      }

    }

    [self.view layoutIfNeeded];

  } completion:^(BOOL finished) {

  }];

其中self.sendBtnHeightLayoutConstraint.constant = 0;将该button进行隐藏,这个用法比较巧妙,由于前面已经 [self.view addConstraint:self.sendBtnHeightLayoutConstraint];因此这里的改变直接影响到self.view,但前提是要调用[self.view layoutIfNeeded];

在show的分支中, self.sendBtnHeightLayoutConstraint.constant = kHeightForSendButton;进行显示。

 

接着是contentOffset的控制,以前的3个condition很容易考虑不全。isInLastPage:由于咱们须要在最后一页移动tableview的bottom;isMoreThanOnePage:而且若是只有一页的话咱们不须要进行操做;!hasAdjustedOffsetY:在连续选择时只在第一次时移动。

最后有个问题,为啥show的适合须要调整contentOffset,hide的时候不须要呢?彷佛也很简单,聪明的你应该已经知道答案了吧!

相关文章
相关标签/搜索