реализация циклического UITableView - PullRequest
6 голосов
/ 03 января 2011

Каков наилучший способ реализовать циклический UITableView, где вместо отображения пустого пространства, когда пользователь прокручивает границы таблицы, он просто циклически оборачивается?Примерами здесь могут быть выбор дня недели, часа в 24-часовом дне или часовых поясов, последовательно упорядоченных по всему земному шару.Есть несколько идей, как взломать это (можно сказать, список 100x7 дней, начиная с середины), но ничего элегантного.

У кого-нибудь есть идеи или опыт?

Дэвид

Ответы [ 5 ]

4 голосов
/ 12 июля 2012

UITableView - это то же самое, что и UIScrollView в методе scrollViewDidScroll.

Итак, его легко эмулировать бесконечной прокруткой.

  1. удваивает массив так, чтобы голова и хвост соединялисьдля эмуляции круглого стола

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

:

/* To emulate infinite scrolling...

The table data was doubled to join the head and tail: (suppose table had 1,2,3,4)
1 2 3 4|1 2 3 4 (actual data doubled)
---------------
1 2 3 4 5 6 7 8 (visualising joined table in eight parts)

When the user scrolls backwards to 1/8th of the joined table, user is actually at the 1/4th of actual data, so we scroll instantly (we take user) to the 5/8th of the joined table where the cells are exactly the same.

Similarly, when user scrolls to 6/8th of the table, we will scroll back to 2/8th where the cells are same. (I'm using 6/8th when 7/8th sound more logical because 6/8th is good for small tables.)

Thus, when user reaches 1/4th of the first half of table, we scroll to 1/4th of the second half, when he reaches 2/4th of the second half of table, we scroll to the 2/4 of first half. This is done simply by subtracting OR adding half the length of the new/joined table.
*/


-(void)scrollViewDidScroll:(UIScrollView *)scrollView_ 
{  

    CGFloat currentOffsetX = scrollView_.contentOffset.x;
    CGFloat currentOffSetY = scrollView_.contentOffset.y;
    CGFloat contentHeight = scrollView_.contentSize.height;

    if (currentOffSetY < (contentHeight / 8.0)) {
    scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY + (contentHeight/2)));
    }
   if (currentOffSetY > ((contentHeight * 6)/ 8.0)) {
       scrollView_.contentOffset = CGPointMake(currentOffsetX,(currentOffSetY - (contentHeight/2)));
    }

}

PS - я использовал этот код в одном из моих приложений под названием NT Time Table (Lite).Если вы хотите предварительный просмотр, вы можете проверить приложение: https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

Если ваша таблица иногда может быть слишком короткой, в начале описанного выше метода вы можете добавить логику if для выхода из метода, когда данныенапример, число меньше 9.

4 голосов
/ 03 января 2011

Я видел такое поведение пару раз, но не в UITableView, а в UIPickerView.Код довольно прост и, вероятно, можно преобразовать в UITableView ....

Код для циклического UIPickerView

RollerViewController.h

@interface RollerViewController : UIViewController <UIPickerViewDelegate>{
    UIPickerView *picker;
}    
@end

RollerViewController.m

#import "RollerViewController.h"

@implementation RollerViewController

#define MAX_ROLL 100
#define ROWS_COUNT 10

#pragma mark -
#pragma mark Helpers

- (void) infinitePickerViewDidSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    NSUInteger base10 = (MAX_ROLL/2) - (MAX_ROLL/2)%ROWS_COUNT;
    [picker selectRow:row%ROWS_COUNT+base10 inComponent:component animated:FALSE];
}

#pragma mark -
#pragma mark UIPickerView dataSource delegate methods

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
    return 3;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
    return MAX_ROLL;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
    return (CGFloat)40;
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    [self infinitePickerViewDidSelectRow:row inComponent:component];
}

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
    return (CGFloat) 50;
}
- (UIView *)pickerView:(UIPickerView *)thePickerView viewForRow:(NSInteger)row 
          forComponent:(NSInteger)component reusingView:(UIView *)rview {

    UILabel *retval = (UILabel *)rview;
    if (!retval) {
        retval= [[[UILabel alloc] initWithFrame:CGRectMake(5,5,40,30) ] autorelease];
    }

    retval.text = [NSString stringWithFormat:@"%d", row%ROWS_COUNT];
    retval.font = [UIFont systemFontOfSize:25];
    retval.textAlignment = UITextAlignmentCenter;
    retval.backgroundColor = [UIColor clearColor];
    return retval;
}

#pragma mark overides

- (void)viewDidLoad {
    [super viewDidLoad];
    picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 280)];
    picker.delegate = self;
    [self.view addSubview:picker];

}
- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    [self infinitePickerViewDidSelectRow:arc4random()%MAX_ROLL inComponent:0];
    [self infinitePickerViewDidSelectRow:arc4random()%MAX_ROLL inComponent:1];
    [self infinitePickerViewDidSelectRow:arc4random()%MAX_ROLL inComponent:2];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)dealloc {
    [picker release];
    [super dealloc];
}

@end
2 голосов
/ 22 апреля 2011

Да, можно сделать циклический UITableView. Вы просто передаете действительно большое число как число строк, а затем для каждой строки, которую запрашивает табличное представление, передаете его row_number% number_of_rows, поэтому вы всегда выполняете итерации в своих данных, даже если номер строки невероятно велик.

Вы можете увидеть пример здесь: http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/

По сути это похоже на UIPickerView, реализованный с помощью UITableView.

0 голосов
/ 14 ноября 2016

Я сделал циклический tableView на основе UIScrollView.И на основе этого tableView я повторно реализую UIPickerView.Вас может заинтересовать этот класс DLTableView.https://github.com/danleechina/DLPickerView

0 голосов
/ 03 января 2011

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

вы можете сделать это для конечного числа, также вы можете повторять строки, но это не позволяет сделать циклический tableView.

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