实现循环UITableView的最佳方法是什么,而不是在用户向上滚动到表格边界时显示空格,它只是循环包裹?这里的示例可能是选择星期几,24小时工作小时,或者按顺序在全球范围内订购时区。有一些想法如何破解这个(可以说是从中间开始的100x7天的列表),但没有什么优雅。
有没有人对此有任何想法或经验?
大卫
答案 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相同。
因此,它很容易模仿无限滚动。
将数组加倍,使头部和尾部连接在一起,以模拟圆形表格
使用我的以下代码,当用户往往到达表的开头或结尾时,用户可以在doubled表的1st部分和doubled表的2nd部分之间切换。
/* 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。