SMGridView 是 UIScrollView 的子类,允许您使用类似于 UITableView、UITableViewDataSource 和 UITableViewDelegate 的方法创建自定义网格。它提供以下支持:
在此处查看完整的API 文档。
要安装,只需克隆项目并将 SMGridView.h 和 SMGridView.m 文件拖入您的项目。这些文件在 SMGridView/source 中。之后,导入 SMGridView.h,您就可以开始使用了。
您可以通过在 xCode 中运行此项目来检查带有许多功能的完整示例。代码非常简单,所有操作都发生在 SMGridViewTest.m
类中。要管理设置,我们使用 inAppSettings,因此该库也包含在此项目中。调整设置以查看网格对更改的反应。
目前此项目不使用 ARC。将其改为支持 ARC 非常简单,但在做到这一点之前,如果您使用 ARC,则需要为 SMGridView 设置 fno-obj-arc
编译器标志。
要在 Xcode 中设置编译器标志,请转到您的活动目标并选择“构建 phases”选项卡。然后选择所有源文件(SMGridView.h 和 SMGridView.m),按 Enter 键,插入 -fobjc-arc
或 -fno-objc-arc
,然后按“完成”。
首先导入头文件。我们将其导入视图控制器中的 .h 文件中,因为我们希望自定义视图控制器成为 SMGridView 的 dataSource 和 delegate。
#import "SMGridView.h"
@interface SMGridViewTestViewController : UIViewController <SMGridViewDataSource, SMGridViewDelegate>
@property (nonatomic, retain) SMGridView *grid;
@end
现在让我们创建 SMGridView。如果您想使用 nib 文件,您可以在界面中创建它并使用 IBOutlet 链接。我将在 viewDidLoad 方法中创建 SMGridView。
@implementation MyViewController
@synthesize grid = _grid;
- (void)viewDidLoad {
[super viewDidLoad];
self.grid = [[[SMGridView alloc] initWithFrame:CGRectMake(0,
0,
self.view.frame.size.width,
self.frame.size.height)] autorelease];
self.grid.dataSource = self;
self.grid.delegate = self;
}
- (void)dealloc {
[_grid release];
[super dealloc];
}
SMGridViewDelegate 中的所有方法都是可选的,但 SMGridDataSource 要求您实现一些方法
// 100 items, only one section (default), so no need to read and adapt for section parameters
- (NSInteger)smGridView:(SMGridView *)gridView numberOfItemsInSection:(NSInteger)section {
return 100;
}
// Return views of size 100x100
- (CGSize)smGridView:(SMGridView *)gridView sizeForIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(100, 100);
}
- (UIView *)smGridView:(SMGridView *)gridView viewForIndexPath:(NSIndexPath *)indexPath {
// Check if we can reuse
UILabel *label = [gridView dequeReusableView];
if (!label) {
label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease]
}
label.text = [NSString stringWithFormat:@"%d", indexPath.row];
return label;
}
我们只需调用 reloadData
方法。就像 UITableView 一样,这个方法实际上会创建视图。让我们在 viewDidLoad 中做这件事。
@implementation MyViewController
@synthesize grid = _grid;
- (void)viewDidLoad {
[super viewDidLoad];
self.grid = [[[SMGridView alloc] initWithFrame:CGRectMake(0,
0,
self.view.frame.size.width,
self.frame.size.height)] autorelease];
self.grid.dataSource = self;
self.grid.delegate = self;
[self.grid reloadData];
}
- (void)dealloc {
[_grid release];
[super dealloc];
}
可以使用 vertical
属性来决定是否为垂直方向(YES)或水平方向(NO)。默认为水平方向(NO)。更改此属性后,需要调用 reloadData。
有一个名为 padding
的属性,你可以设置它来决定网格中对象与网格边缘之间的空间。
如果你想添加或移除一个项,你只需适配 dataSource(应返回不同的数量)并调用 reloadData。然而,SMGridView 支持 animating 添加或移除项。
要在 dataSource 准备好后使用动画添加视图,应调用
- (void)addItemAtIndexPath:(NSIndexPath *)indexPath;
一次。
移除一个项稍微复杂一些(但不多!)首先,在没有调整 dataSource 的情况下,你调用
- (void)removeItemAtIndexPath:(NSIndexPath *)indexPath;
一旦网格滚动到需要移除项的位置,dataSource 将收到一个调用
- (void)smGridView:(SMGridView *)gridView performRemoveIndexPath:(NSIndexPath *)indexPath;
这就是你要适配 dataSource 的时候。至此,大功告成!
该项目包含如何使用 SMGridView 的示例。要测试它,只需在 XCode 中打开项目文件并运行它。你可以按 Edit 按钮来更改一些设置。源代码有注释,但应该很容易理解。注意,我们没有使用 nib 文件。
为了使用拖放功能对网格进行排序,你的视图应属于 UIControl
的子类。然后你需要将 enableSort
设置为 YES。一旦你将项拖放到新位置,这个方法将在 SMGridViewDataSource
中被调用
- (void)smGridView:(SMGridView *)gridView
shouldMoveItemFrom:(NSIndexPath *)fromIndexPath
to:(NSIndexPath *)indexPath;
在此方法的实现中,你应该相应地更改 dataSource 以反映顺序变化。目前你只能对同一部分的项进行排序。不允许进行相应的部分更改(暂时如此)。
SMGridView 支持 parts。为了拥有不同的部分,在 SMGridViewDataSource
中实现以下方法
- (NSInteger)numberOfSectionsInSMGridView:(SMGridView *)gridView;
所有的 SMGridViewDataSource
方法都会传递一个 NSIndexPath 对象。你可以像对待 UITableView 那样访问这个对象的 section 和 row 属性。
你可以像在 UITableView 中一样拥有部分标题。只需在你的 dataSource 中实现这两个方法
- (CGSize)smGridView:(SMGridView *)gridView sizeForHeaderInSection:(NSInteger)section;
- (UIView *)smGridView:(SMGridView *)gridView viewForHeaderInSection:(NSInteger)section;
如果你的标题需要固定在网格的顶部,只需在 SMGridView 中将 stickyHeaders
属性设置为 YES。
SMGridView 需要知道所有项的大小来计算滚动内容有多长。这就是为什么 dataSource 有这个方法
- (CGSize)smGridView:(SMGridView *)gridView sizeForIndexPath:(NSIndexPath *)indexPath;
但是,如果所有的视图都有相同的大小,SMGridView 可以有更好的性能。如果是这种情况,只需在 SMGridViewDataSource
中实现此方法,如下所示
- (BOOL)smGridViewSameSize:(SMGridView *)gridView {
return YES
}
这提高了性能,因为 SMGridView 将进行更少的计算。
您可以通过将 pagingEnabled
属性设置为 YES 来启用分页。然而,章节标题目前还不与分页兼容,因此您不应将这两个功能结合起来。
在滚动时加载更多内容是一个常见的模式。如果滚动到底部时您还在加载更多内容,则在底部显示一个加载器非常有用。SMGridView提供了对这些功能的支持。要在网格底部显示自定义视图,您需要做两件事:1. 将 loaderView
属性设置为要显示的 UIView。2. 在 SMGridViewDataSource
中实现此方法
- (BOOL)smGridViewShowLoader:(SMGridView *)gridView;
并在需要显示加载器时返回 YAML。通常情况下,dataSource 将知道您何时仍在加载内容或何时完成,因此此方法应反映这一点。
如果您正在使用加载器,并希望将100个更多项目添加到网格的底部,您可以直接调用 reloadDataOnlyNew
,而不是调用 reloadData
。这将提高网格的性能,因为它只需要为新项目计算位置,而不需要整个网格。
SMGridView采用MIT许可。有关所有复杂细节,请参阅附带的 LICENSE 文件。