在上教程中,我们介绍了二级导航栏的开发,今天我们来讲解iOS开发中非常常用和重要的组件:“列表”,即UITableView。本节课程将会介绍横向滚动列表和竖向滚动列表,分别来实现二级栏目滑动切换和新闻内容列表的功能。
UITableView介绍
在OC中,UITableView是用来展示列表数据的控件,基本使用方法是:
1.首先,Controller需要实现两个delegate ,分别是UITableViewDelegate 和UITableViewDataSource
2.然后 UITableView对象的 delegate要设置为 self。
3.实现这些delegate的一些方法,重写。
横向滚动列表-二级栏目滑动切换
1.新建横向滚动列表类LandscapeTableView
//LandscapeTableView.h
#import <UIKit/UIKit.h>
#import "LandscapeCell.h"
@protocol LandscapeTableViewDelegate;
@protocol LandscapeTableViewDataSource;
@interface LandscapeTableView : UIView <UIScrollViewDelegat\> {
// 存储页面的滚动条容器
UIScrollView *_scrollView;
// 单元格之间的间隔,缺省20
CGFloat _gapBetweenCells;
// 预先加载的单元格数,在可见单元格的两边预先加载不可见单元格的数目
NSInteger _cellsToPreload;
// 单元格总数
NSInteger _cellCount;
// 当前索引
NSInteger _currentCellIndex;
// 上次选择的单元格索引
NSInteger _lastCellIndex;
// 加载当前可见单元格左边的索引
NSInteger _firstLoadedCellIndex;
// 加载当前可见单元格右边的索引
NSInteger _lastLoadedCellIndex;
// 可重用单元格控件的集合
NSMutableSet *_recycledCells;
// 当前可见单元格集合
NSMutableSet *_visibleCells;
// 是否正在旋转
BOOL _isRotationing;
// 页面容器是否正在滑动
BOOL _scrollViewIsMoving;
// 回收站是否可用,是否将不用的页控件保存到_recycledCells集合中
BOOL _recyclingEnabled;
}
@property(nonatomic, assign) IBOutlet id<LandscapeTableViewDataSource> dataSource;
@property(nonatomic, assign) IBOutlet id<LandscapeTableViewDelegate> delegate;
@property(nonatomic, assign) CGFloat gapBetweenCells;
@property(nonatomic, assign) NSInteger cellsToPreload;
@property(nonatomic, assign) NSInteger cellCount;
@property(nonatomic, assign) NSInteger currentCellIndex;
// 重新加载数据
- (void)reloadData;
// 由索引获得单元格控件,如果该单元格还没有加载将返回nil
- (LandscapeCell *)cellForIndex:(NSUInteger)index;
// 返回可以重用的单元格控件,如果没有可重用的,返回nil
- (LandscapeCell *)dequeueReusableCell;
@end
@protocol LandscapeTableViewDataSource
@required
- (NSInteger)numberOfCellsInTableView:(LandscapeTableView *)tableView;
- (LandscapeCell *)cellInTableView:(LandscapeTableView *)tableView atIndex:(NSInteger)index;
@end
@protocol LandscapeTableViewDelegate
@optional
- (void)tableView:(LandscapeTableView *)tableView didChangeAtIndex:(NSInteger)index;
- (void)tableView:(LandscapeTableView *)tableView didSelectCellAtIndex:(NSInteger)index;
// a good place to start and stop background processing
- (void)tableViewWillBeginMoving:(LandscapeTableView *)tableView;
- (void)tableViewDidEndMoving:(LandscapeTableView *)tableView;
@end
#import "LandscapeTableView.h"
@interface LandscapeTableView (LandscapeTableViewPrivate) <UIScrollViewDelegate>
- (void)configureCells;
- (void)configureCell:(LandscapeCell *)cell forIndex:(NSInteger)index;
- (void)recycleCell:(LandscapeCell *)cell;
- (CGRect)frameForScrollView;
- (CGRect)frameForCellAtIndex:(NSUInteger)index;
- (void)willBeginMoving;
- (void)didEndMoving;
@end
@implementation LandscapeTableView
#pragma mark - Lifecycle methods
- (void)addContentView
{
_scrollView = [[UIScrollView alloc] initWithFrame:[self frameForScrollView]];
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_scrollView.pagingEnabled = YES;
_scrollView.backgroundColor = [UIColor whiteColor];
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.bounces = YES;
_scrollView.delegate = self;
[self addSubview:_scrollView];
}
- (void)internalInit
{
_visibleCells = [[NSMutableSet alloc] init];
_recycledCells = [[NSMutableSet alloc] init];
_currentCellIndex = -1;
_lastCellIndex = 0;
_gapBetweenCells = 20.0f;
_cellsToPreload = 1;
_recyclingEnabled = YES;
_firstLoadedCellIndex = _lastLoadedCellIndex = -1;
self