【问题标题】:UIRefreshcontrol jitters when pulled down and held下拉并按住时 UIRefreshcontrol 抖动
【发布时间】:2014-04-09 03:09:24
【问题描述】:

我在我的 tableviewcontroller 中创建了一个 UIRefreshcontrol,如下在 viewdidload 方法中:

    refresh = [UIRefreshControl.alloc init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshChatsTableView) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;

问题在于,当我将其拉长一点时,表格会抖动起来,给人一种非常不愉快的 UI 体验。有人可以帮忙吗?此行为仅在横向模式下才会出现。

这是我的代码:

-UIRefreshControl  *refresh;

    -(void)viewDidLoad{
        [super viewDidLoad];
         arr= [[NSArray    alloc]initWithObjects:@"A",@"B",@"C",@"D",@"E",@"A",@"B",@"C",@"D",@"E", nil];

        //refresh control
        refresh = [UIRefreshControl.alloc init];
        refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to   Refresh"];
        [refresh addTarget:self action:@selector(refreshChatsTableView)  forControlEvents:UIControlEventValueChanged];
        self.refreshControl = refresh;
      }


    -(void)refreshChatsTableView{
        [refresh endRefreshing];
    }

    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return 1;
    }

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
       return arr.count;
    }

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell =[[UITableViewCell alloc]init];
        cell.textLabel.text = [arr objectAtIndex:indexPath.row ];

        return cell;
    }

【问题讨论】:

  • 这不正常。也许您正在其他地方调整内容偏移量?
  • 不!我不会在任何地方改变它。事实上,我创建了一个新示例,我只是在表格中填充了一个数组并添加了这个控件。你从来没有经历过这个吗?
  • 我已经用我的代码更新了帖子

标签: ios objective-c ios7 pull-to-refresh uirefreshcontrol


【解决方案1】:

通常你使用 UIRefreshControl 来触发异步重新加载操作,并且应该在经过一定时间后调用 endAnimating。它看起来就像刷新控件开始动画的那一刻,您立即结束它。这可能会让 UIRefreshControl 感到困惑。

在经过一段时间后尝试调用 endAnimating,或者在另一个 runloop 循环中(例如在 dispatch_async 中调用它)。您的代码似乎存在其他问题(例如,您的 tableView:cellForRowAtIndexPath: 创建单元格不正确),因此可能存在其他问题。

【讨论】:

    【解决方案2】:

    尝试改变

    self.refreshControl = refresh;
    

    [self.tableView addSubview:refresh];
    [self.tableView sendSubviewToBack:refresh];
    

    +++++++++++ 如果您在触发第一个 refreshControl 时出现了属性字符串布局问题 - 在将 refreshControl 添加为子视图后添加它

    dispatch_async(dispatch_get_main_queue(), ^{
        [refreshControl beginRefreshing];
        [refreshControl endRefreshing];
    });
    

    【讨论】:

      【解决方案3】:

      只需在[refresh endRefreshing] 之后添加tableView.alwaysBounceVertical = YES,这样表格就会在刷新控件结束动画后弹回顶部。

      【讨论】:

        【解决方案4】:

        所以我刚刚遇到了同样的问题,我想出了一个解决方案。基本上,如果您将 tableView 拉得足够远并按住它,ValueChanged 控件事件将在用户释放触摸之前触发。如果此时刷新数据并重新加载tableView,表格会跳起来。

        为了解决这个问题,我最终独立于 ValueChanged 事件刷新了表格。相反,我使用该事件以及 scrollView 委托方法,仅在用户放手后刷新表格。

        首先,在 viewDidLoad 中设置您的 refreshControl。

        override func viewDidLoad()
        {
            super.viewDidLoad()
        
            refreshControl = UIRefreshControl()
            refreshControl?.addTarget(self, action: "refreshControlChanged", forControlEvents: UIControlEvents.ValueChanged)
        }
        

        ValueChanged 方法很简单。如果我们已经停止拖动(在快速向下滑动后发生),只需使用您自己的自定义方法刷新表格即可。

        internal func refreshControlChanged()
        {
            if !tableView.dragging
            {
                refresh()
            }
        }
        

        然后,您需要实现 didEndDragging。如果你拉得足够远,refreshControl 将会刷新,所以调用 refresh。否则,您要么拉得不够远,要么拖到表格的不同部分,要么拖得太快,以至于 refreshControl ValueChanged 事件尚未触发,它会刷新那里的表格。

        override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
        {
            if refreshControl?.refreshing == true
            {
                refresh()
            }
        }
        

        就是这样。直到您停止拖动表格后,表格才会重新加载,这避免了您注意到的紧张跳跃。我知道这已经有一年了,但我希望这可以帮助其他在 Google 上遇到此问题的人。

        【讨论】:

        • 此解决方案有效,但释放拉取后表格会跳转。桌子不应该跳,但应该平稳上升。有什么解决办法吗?
        【解决方案5】:

        SWIFT 4:

        在 ViewdidLoad() 中

        someCollectionView 或 someTableView

        someCollectionView.refreshControl?.addSubview(refreshControl)
        someCollectionView.refreshControl?.sendSubview(toBack: refreshControl)
        

        非常适合我。

        【讨论】:

          【解决方案6】:

          我的解决方案类似于公认的解决方案。这个想法是仅在视图位于正确位置后更新您的表视图。因此,我们可以添加一个变量来跟踪滚动视图完全弹回时是否需要更新视图(减速时不要更新)。

          另外,请务必在结束 refreshControl 之前更新您的表格视图。

          // The action function of refreshControl
          @objc private func refresh() {
              DispatchQueue.global(qos: .utility).async {
                  // Update data
                  // ......
          
                  // Update the table view
                  DispatchQueue.main.async {
                      if self.tableView.isDragging == false {
                          self.tableView.reloadData()
                          self.myRefreshControl.endRefreshing()
                      } else {
                          self.needEndRefreshing = true
                      }
                  }
              }
          }
          
          override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
              if self.needEndRefreshing {
                  self.tableView.reloadData()
                  self.myRefreshControl.endRefreshing()
                  self.needEndRefreshing = false
              }
          }
          

          【讨论】:

            【解决方案7】:

            @Devin 的回答确实有帮助,但对我来说完全解决问题的是让我的 NavigationBar “半透明”。 https://i.stack.imgur.com/TKcdH.png

            当 UIControlEventValueChanged 因某种原因被触发时,使用非半透明 NavigationBar 会导致 tableview 略微跳起。

            XCode 10.1

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-05-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-02-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多