Прокрутка UITableView плавная с определенной скоростью? - PullRequest
18 голосов
/ 20 октября 2010

Я создаю пользовательский игровой автомат с колонкой, которая существует из uitableview.

Когда пользователь нажимает на рычаг, табличное представление должно перейти к определенной позиции с индексом. Я использовал метод:

- scrollToRowAtIndexPath:atScrollPosition:animated:

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

Я ищу способ: А) Замедлите анимацию прокрутки. Или же, Б) Измените продолжительность анимации прокрутки на самоопределяемое значение.

Обычная анимация прокрутки (с помощью пальца) показывает этот эффект. Может быть, это глупая идея, но это идея вызывать методы touchesBegan и touchesDidEnd в моем tableView?

Спасибо уже

Ответы [ 8 ]

17 голосов
/ 20 апреля 2011

Может, нужно посмотреть в этом направлении?

 [UIView animateWithDuration: 1.0
                  animations: ^{
                      [tableViewExercises scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:previousSelectedExerciseCell inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
                  }completion: ^(BOOL finished){
                  }
    ];

Работа только с анимацией: НЕТ.

13 голосов
/ 15 октября 2011

Поскольку UITableView наследуется от UIScrollView, вы также можете использовать setContentOffset: animated: Таким образом, вы можете сделать так, чтобы табличное представление «прокручивало» определенное количество пикселей по вашему выбору на любую сторону.

Это можно сделать так же с scrollToRowAtIndexPath: atScrollPosition: animated:

Я сделал прототип, чтобы показать вам, как он работает.

Поскольку это делается с помощью таймеров и прочего, вы можете установить, как долго будет длиться автопрокрутка и как быстро (и как далеко, если вы используете смещение содержимого) анимация будет идти.

Это файл .h:

#import <UIKit/UIKit.h>

@interface AutomaticTableViewScrollViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
    UITableView *slotMachine;
    NSMutableArray *listOfItems;
    NSTimer *tableTimer;
}

@property (nonatomic,retain) UITableView *slotmachine;
@property (nonatomic,retain) NSMutableArray *listOfItems;
@property (nonatomic,retain) NSTimer *tableTimer;

-(void)automaticScroll;
-(void)stopscroll;

@end

Это файл .m:

#import "AutomaticTableViewScrollViewController.h"

@implementation AutomaticTableViewScrollViewController

@synthesize slotmachine;
@synthesize listOfItems;
@synthesize tableTimer;

-(void)loadView
{
    [super loadView];

    slotmachine = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
    slotmachine.delegate = self;
    slotmachine.dataSource = self;
    [self.view addSubview:slotmachine];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Set up the cell...
    if (indexPath.row % 2 == 0) 
    {
        cell.textLabel.text = @"blalala";
    }

    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 99999;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //you might want to do this action in ur buttonTargetMethod
    //start timers
    tableTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 //this value arranges the speed of the autoScroll
                                                   target:self
                                                 selector:@selector(automaticScroll)
                                                 userInfo:nil
                                                  repeats:YES];

    [NSTimer scheduledTimerWithTimeInterval:5 //this arranges the duration of the scroll
                                     target:self
                                   selector:@selector(stopscroll)
                                   userInfo:nil
                                    repeats:NO]; 
}

-(void)automaticScroll
{
    [slotmachine setContentOffset:CGPointMake(slotmachine.contentOffset.x, slotmachine.contentOffset.y + 50) animated:YES]; //the 50 stands for the amount of movement every tick the timer will make
}

-(void)stopscroll
{
    //stop tabletimer again
    [tableTimer invalidate];
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

@end

Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии, и я уточню.

3 голосов
/ 15 октября 2011

Если вам нужна iOS 5, вы можете использовать UIScrollViewDelegate метод scrollViewWillEndDragging:withVelocity:targetContentOffset:. Это позволяет увидеть, насколько быстро пользователь двигал палец, где анимация замедления заканчивается со скоростью по умолчанию, и позволяет переопределить скорость анимации, чтобы она заканчивалась в другой точке.

1 голос
/ 06 июня 2013

Я много искал этот ответ, но в итоге мне пришлось придумать свой собственный.Вы можете вызвать метод scrollAutomatics с начальным номером строки, например:

[self scrollAutomatically:0];

Так выглядит эта функция.Я имел дело с таблицей, в которой всегда было 3000 строк, и намеревался прокрутить ее до конца.

- (void) scrollAutomatically:(int) i
{
    __block int j = i;
    [UIView animateWithDuration: 0//Change this to something more for slower scrolls
                     animations: ^{
                         [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:j inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
                     }
                     completion: ^(BOOL finished){
                         j = j + 10;//Changing this number affects speed.
                         if(j<=2999)//here you could provide the index of destination row
                             [self scrollAutomatically:j];
                         else
                         {
                             //I had some code here that popped up a UIAlertView.
                         }
                     }];
}

Теперь перейдем к скорости прокрутки.

ДЛЯ ДЕЙСТВИТЕЛЬНО БЫСТРЫХ СВИТОК:

Если установить значение, на которое я увеличиваю индекс строки (j) при каждом вызове функции, до 10, т.е. если я пишу j = j+10;, то мои 3000для прокрутки строк потребовалось около 9 секунд.(3000 * означают FPS, которые я мог собрать).Если я установлю его на j = j+20;, то 3000 строк заняли около 4,5 секунд.Итак, вы поняли.Чтобы сделать прокрутку медленнее, уменьшите значение приращения.

ДЛЯ МЕДЛЕННЫХ, ЧИТАЕМЫХ СВИТОК:

[UIView animateWithDuration: 1.5//this will directly set your speed. n rows scrolled every 1.5 seconds.

ПРИМЕЧАНИЕ. Если вы меняете фреймы CALayers или Views (например, customView, который вы могли добавитьк contentView вашего tableViewCell), тогда эти анимации начнут вас беспокоить.При большой продолжительности анимации они будут очень заметны, и вы можете увидеть странное поведение клетки.

В этом случае, где бы вы ни меняли свои кадры и т. Д., Смотрите на что-то вроде:

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[myView.myCALayer.frame = (CGRect){ { 10, 10 }, { 100, 100 } ];
[CATransaction commit];

Найтивышеприведенное решение здесь .

Возможно, вам также потребуется установить словарь действий для слоя, чтобы он возвращал значения NULL для всех действий.

NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"sublayers", nil];
superlayer.actions = newActions;

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

Редактировать: Ой, я вижу точную вещь выше моего ответа :( В любом случае, это немного более подробноа я только начинающий :) 1032 *

1 голос
/ 21 октября 2011

Я использовал функции анимации в Sparrow Framework для создания похожих анимаций.

Ссылка выше имеет пример того, как ее настроить. Вы можете анимировать любое числовое свойство любого объекта Objective C, и вы можете использовать такие переходы, как «легко вводить», «облегчать переход», «упрощать эластичность» и т. Д., Или просто старые добрые линейные анимации.

Свойство contentSize представляет собой CGPoint , поэтому вам фактически потребуется анимировать другое свойство в одном из ваших классов, а затем реализовать фактический метод для функции установщика свойства, чтобы он обновляет contentOffset.

- (void) setTableScrollPosition:(CGFloat)position
{
    CGPoint newOffset = CGPointMake(0.0, position);
    scrollView.contentOffset = newOffset;
}
1 голос
/ 21 октября 2011

Как насчет настройки таймера, а затем вызвать свиток при срабатывании таймера:

start_index = 0;
dest_index = 20;
timer = [NSTimer scheduledTimerWithTimeInterval:(0.1) target:self selector:@selector(rolling) userInfo:nil repeats:YES];                


- (void)rolling {
start_index++;
if (start_index < dest_index) {
    NSIndexPath *Index = [NSIndexPath indexPathForRow:start_index inSection:0];
    [self.tableView scrollToRowAtIndexPath:Index atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
} else {
    [timer invalidate];
}
}
1 голос
/ 15 октября 2011

общий способ сделать приложения-игровые автоматы с UIPickerView, может быть, вы должны проверить это ..

0 голосов
/ 21 октября 2011

Вы не можете (насколько я знаю, я везде искал способ сделать это), чтобы скорость не была постоянной для

- scrollToRowAtIndexPath:atScrollPosition:animated:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...