实现循环UITableView

时间:2011-01-03 12:01:19

标签: iphone uitableview

实现循环UITableView的最佳方法是什么,而不是在用户向上滚动到表格边界时显示空格,它只是循环包裹?这里的示例可能是选择星期几,24小时工作小时,或者按顺序在全球范围内订购时区。有一些想法如何破解这个(可以说是从中间开始的100x7天的列表),但没有什么优雅。

有没有人对此有任何想法或经验?

大卫

5 个答案:

答案 0 :(得分:4)

我已经看过几次这种行为但是在UITableView中却没有UIPickerView。代码非常简单,可能转换为UITableView ....

ciclic 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

答案 1 :(得分:4)

UITableView与scrollViewDidScroll方法中的UIScrollView相同。

因此,它很容易模仿无限滚动。

  1. 将数组加倍,使头部和尾部连接在一起,以模拟圆形表格

  2. 使用我的以下代码,当用户往往到达表的开头或结尾时,用户可以在doubled表的1st部分和doubled表的2nd部分之间切换。

  3. /* 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)));
        }
    
    }
    

    P.S。 - 我在我的一个名为NT Time Table(Lite)的应用程序中使用了这段代码。如果您想要预览,可以查看应用:https://itunes.apple.com/au/app/nt-time-table-lite/id528213278?mt=8

    如果您的表有时太短,在上述方法的开头,您可以添加一个if逻辑,以便在数据计数例如小于9时退出该方法。

答案 2 :(得分:2)

是的,可以制作循环UITableView。您只需传递一个非常大的数字作为行数,然后对于表视图请求的每一行,您将传递给row_number%number_of_rows,因此即使行数非常大,您也总是在数据中进行迭代。

您可以在此处查看示例:http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/

基本上它就像用UITableView实现的UIPickerView。

答案 3 :(得分:0)

我已经基于UIScrollView创建了一个循环tableView。基于这个tableView,我重新实现了UIPickerView。您可能对此课程DLTableView感兴趣。 https://github.com/danleechina/DLPickerView

答案 4 :(得分:-3)

你不能制作循环表。假设你从numberOfRowsInSection方法(有限数字)返回大量的行,那么也有一个上端和cource的表,你不能返回无限的行数,这就是为什么它有结束。所以它看起来不像圆桌。

你可以为有限的数字做它也可以重复行但是这不可能制作循环tableView。