UIRfreshcontrol дрожит при нажатии и удержании

Я создал UIRefreshcontrol в моем tableviewcontroller следующим образом в методе viewdidload:

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

проблема в том, что когда я тяну его немного вниз, стол дрожит, создавая довольно неприятный пользовательский интерфейс. Кто-нибудь может помочь? Такое поведение наблюдается только в ландшафтном режиме.

Вот мой код:

-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;
    }

person Anum Malik    schedule 06.03.2014    source источник
comment
Это ненормально. Возможно, вы настраиваете смещение контента в другом месте?   -  person Aaron Brager    schedule 06.03.2014
comment
Неа !! Я его нигде не меняю. На самом деле, я создал новый образец, в котором я просто заполняю таблицу массивом и добавляю этот элемент управления. Вы никогда не сталкивались с этим?   -  person Anum Malik    schedule 06.03.2014
comment
Я обновил пост своим кодом   -  person Anum Malik    schedule 06.03.2014


Ответы (7)


Итак, я столкнулся с этой же проблемой и нашел решение. По сути, если вы потянете свой tableView достаточно далеко и удержите его, событие управления ValueChanged сработает до того, как пользователь отпустит касание. Если вы обновите свои данные и перезагрузите tableView в этот момент, таблица подпрыгнет.

Чтобы бороться с этим, я обновил таблицу независимо от события ValueChanged. Вместо этого я использовал это событие вместе с методами делегата scrollView, чтобы обновить таблицу только после того, как пользователь отпустил ее.

Итак, сначала настройте свой refreshControl в viewDidLoad.

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 будет обновляться, поэтому вызовите обновление. В противном случае вы либо не опустились достаточно далеко, либо перетаскивали в другую часть таблицы, либо перетаскивали так быстро, что событие refreshControl ValueChanged еще не сработало, и оно обновит таблицу там.

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

Вот и все. Таблица не будет перезагружена до тех пор, пока вы не перестанете ее перетаскивать, что позволяет избежать дрожащего скачка, который вы заметили. Я знаю, что этому уже год, но я надеюсь, что это поможет кому-нибудь еще найти это в Google.

person Devin    schedule 14.07.2015
comment
Это решение работает, но таблица прыгает после того, как пулл отпускается. Стол не должен прыгать, а должен плавно подниматься вверх. Есть ли какое-нибудь решение для этого? - person Raymond; 22.03.2020

попробуй изменить

self.refreshControl = refresh;

для

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

+++++++++, если у вас есть проблемы с макетом attributeString с первым запуском refreshControl - добавьте это после добавления refreshControl в качестве подпредставления

dispatch_async(dispatch_get_main_queue(), ^{
    [refreshControl beginRefreshing];
    [refreshControl endRefreshing];
});
person tholub    schedule 05.06.2014

Просто добавьте tableView.alwaysBounceVertical = YES после [refresh endRefreshing], чтобы таблица подпрыгнула вверх после того, как элемент управления обновлением закончил свою анимацию.

person teach    schedule 10.10.2014

Мое решение похоже на принятое решение. Идея состоит в том, чтобы обновить табличное представление только после того, как представление окажется в нужном месте. Следовательно, мы можем добавить переменную для отслеживания, если нам нужно обновить представление, когда представление прокрутки полностью возвращается (не обновляйте его во время замедления).

Кроме того, всегда обновляйте представление таблицы перед завершением 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
    }
}
person Jay Wong    schedule 03.01.2019

Обычно вы используете UIRefreshControl для запуска асинхронной операции перезагрузки, а endAnimating следует вызывать по истечении определенного периода времени. Здесь выглядит так, как будто в тот момент, когда элемент управления обновлением начинает анимацию, вы немедленно заканчиваете ее. Вероятно, это сбивает с толку UIRfreshControl.

Попробуйте вызвать endAnimating по истечении определенного периода времени или в другом цикле выполнения (например, вызовите его в dispatch_async). Похоже, что в вашем коде есть и другие проблемы (например, ваш tableView:cellForRowAtIndexPath: неправильно создает ячейки), поэтому там могут скрываться другие проблемы.

person Michael Nachbaur    schedule 30.04.2014

SWIFT 4:

В ViewdidLoad()

SomeCollectionView или SomeTableView

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

Работал отлично для меня.

person David Lintin    schedule 26.03.2018

@ Ответ Девина действительно помог, но что полностью решило проблему для меня, так это сделать мою панель навигации «Прозрачной». https://i.stack.imgur.com/TKcdH.png

Использование непрозрачной панели навигации приводит к тому, что табличное представление слегка подпрыгивает, когда по какой-то причине запускается UIControlEventValueChanged.

X-код 10.1

person qijaz221    schedule 05.01.2019