Blast 0.0.35

Blast 0.0.35

Bob de Graaf 维护。



Blast 0.0.35

  • 撰写的作者:
  • Bob de Graaf

Blaze

使用 Blaze,我可以比平时快70%地开发应用。Blaze不是一个单一任务的简单框架,而是一个用于以闪电速度开发应用的强大框架。

你应该什么时候使用 Blaze?

  • 当你对设计师没有考虑到小型设备而感到烦恼时,需要每块屏幕都支持可滚动。
  • 当你喜欢自动布局(不是在代码中)并想尽可能地使用它时
  • 当你创建许多具有不同设计的应用程序,并且需要高度的灵活性来支持那些设计时
  • 当你有文本字段,并且厌倦了确保键盘不覆盖文本字段时
  • 当你厌倦了反复编写相同的模板代码时

已经有很多版本的Blaze,但最终版本太过出色,以至于我(和我所在公司里的所有人)在应用中的每个屏幕上都在使用Blaze,并且我们无法想象不再使用Blaze。有兴趣阅读有关我如何创建Blaze以及它是如何最终形成这个最终版本的详细版本吗?请点击以下链接阅读我关于Blaze的博客:点击这里阅读我的Blaze博客!

简短版:

  • 新的 iPhone6 和 6+ 尺寸导致了设计变化。设计师开始以iPhone6为基准分辨率设计。
  • 这导致了一个问题:99%的屏幕无法适应iPhone4,从而产生了几乎每块屏幕都需要可滚动的能力。
  • 在界面构建器中使用scrollviews进行autolayout是非常戏剧化的。所以我不得不使用collectionviews或tableviews,然后在使用单元格内的autolayout。
  • 只要正确设置了约束,UITableviewcells结合UITableViewAutomaticDimension是非常棒的。不幸的是,在collectionviews中,这些自动维度计算仍然存在太多bug...所以依然是UITableView
  • 我不想使用会滚动内容以避免键盘覆盖的框架,比如TPKeyboardAvoiding,或者编写我自己的版本,因为它们太脆弱,并且在100%的情况下不能正常工作。因此,我不能使用内部包含tableview的custom UIViewController。UITableViewcontroller自带一个向上滚动内容的完美功能,这样键盘就不会覆盖输入字段。所以,是UITableViewController
  • 所以,我开始为每个界面都使用 `UITableViewController`!(或者对于某处始终可见按钮的界面,使用 `contaierviews`)
  • 因此,我对每个界面的大量样板代码感到烦恼...
  • 我检查了可用的 '表单框架',这些框架可以快速创建基于对象等的 `tableviewcontrollers`。大多数这些框架的问题是,在接口构建器中没有自定义设计的选项。通常,你唯一能做的就是使用代码更改标签的字体。但是,我需要创建具有如此不同设计的应用程序,我需要最高的灵活性。除此之外,这些框架通常不支持动态单元格。例如,我需要一个当你在单元格中翻转 `UISwitch` 时,另一个单元格会动态添加/删除的功能。
  • 结论 - 我不得不创建自己的框架!所以我创建了 Blaze,添加了大量的功能,我简直无法想象没有它我的生活会是怎样的:)

关于文档的说明
由于我一直专注于开发,所以文档有些落后。我肯定会在这接下来的几周里不断改进它!

基本功能

首先使用 CocoaPods 安装

pod 'Blaze'

然后呢?

你可以通过创建 `BlazeTableViewController` 的子类来使用 Blaze。Blaze 的基础思想是你可以创建多个指向相同代码的 XIB。是的,这是可能的,也很酷 :) 我有时需要创建包含许多输入字段的应用程序,所以我为 XIB-file 创建了几个基础的输入单元格。就像我说的,我这样设置是为了你可以有你想的任何非常规设计,但你仍然不需要编辑任何代码。所以你可以只创建 XIB-files 并玩转自动布局,这不是很有趣吗?所以我创建了以下基本代码单元格:

  • UITextField 输入
  • UITextView 输入(是的,当输入很多时,行高会自动增加)
  • UISwitch 输入
  • UISlider 输入
  • UIDate 输入(在键盘的 inputView 内使用)
  • UIPickerView 输入(在键盘的 inputView 内使用)
  • UISegmentedControl 输入
  • 复选标记输入
  • 两种选项输入(例如选择性别 - 男/女)
  • 等等,随着我打字列表在增长 :)

Blaze 最酷的功能之一就是它可以根据 Xib 名称自动知道使用哪种代码为单元格。这是因为 XIB 可以指向你想要的任何代码文件,XIB 的名称不一定非得和代码文件的名称一样。上述所有这些输入单元格均具有出色的完成块,你无需编写任何代码,例如 UITextField 代理内容。更多内容请参阅下文。

我还发现我通常有些单元格没有任何输入。仅仅是一个标签和几个图片视图,也许有一个按钮。所以,我创建了一个基类单元格 BlazeTableViewCell(所有输入单元格都是其子类),其中有许多可连接的输出。目前支持

  • 3 个 UILabel(支持正常和属性文本)
  • 3 个 UIImageView(支持 UIImage、NSData 和 NSURL - 对于 URL,它使用 AFNetworking 的优秀 UIImageview 分类)
  • 3 个 UIView(支持 UIColor)
  • 3 个 UIButton(带有完成块)这应该覆盖了大多数单元格?你可以在 InterfaceBuilder 中简单地连接必要的 IBOutlets 并忽略你不使用的那些。如上所述,所有输入单元格都是这个类的子类,所以你总是会拥有所有这些输出!如果你觉得这些输出还不够以满足你超定制的单元格,你可以使用一个返回 UITableViewCell 的出色完成块来进一步自定义它(请参阅一些关于此的代码示例:)

如何实际使用它?

我建议首先创建一个名为 BaseTableViewController 的子类,然后为你的 App 中的每个屏幕创建该类的子类。这样,如果你有某些部分高度,你只需在一个地方设置即可。此外,你可以在一个地方注册在不同屏幕中重复使用的所有单元格。

然后,当你创建屏幕时,你可以使用几行代码创建部分和行。

BlazeSection *section = [[BlazeSection alloc] initWithHeaderXibName:xibName title:@"Title"];
[self addSection:section];

BlazeRow *row = [[BlazeRow alloc] initWithXibName:xibName title:@"Title"];
[section addRow:row];

就这样,你只是创建了一个包含标题部分和单元格的全屏。这是易于使用单元格所需的全部代码。当然,BlazeSection 和 BlazeRow 有许多其他附加选项。部分可以有标题/页脚标题和 xibnames,行具有所有可能单元格类型的大量选项,例如对于文本字段,你可以设置 keyboardType、capitalizationType 等。这里有更多示例(但请务必查看示例项目:)

不带输入的静态单元格

如果你有一些不会再次使用的单元格,你只需要创建并设计XIB,并将其指向 BlazeTableViewCell 类。然后只需一行代码即可。

[section addRow:[BlazeRow rowWithXibName:xibName]];

无输入的可复用单元格

对于无输入的可复用单元格,你应该始终创建一个指向基本 BlazeTableViewCell 的XIB文件。然后在界面构建器中正确分配标签/图像,并根据以下方式设置行。

BlazeRow *row = [BlazeRow rowWithXibName:xibName];
row.imageNameLeft = @"PictureImageFromBundle";
row.title = @"Title for the cell";
row.subtitle = @"Subtitle";
row.imageURLRight = @"Url for the image on the right";
[section addRow:row];

如果你有按钮或单元格选择的操作,你可以添加简单的完成块。

[row setButtonCenterTapped:^{
//Button tapped!
}];
[row setCellTapped:^{
//Cell tapped!
}];

带有输入/值的单元格

对于带输入的单元格,首先检查Blaze是否支持输入类型。大多数基本输入类型,如UITextfield、UITextView、UISwitch等,已经得到支持并在代码中创建。因此,您只需要创建XIB,分配IBOutlets,并指向正确的类。所有支持的输入单元格都有返回值的完成块,因此您无需编写任何附加代码。对于UITextfield,您需要将XIB指向 BlazeTextFieldTableViewCell 类,并按以下方式设置。

BlazeRow *row = [[BlazeRow alloc] initWithXibName:xibName];
row.title = @"Title possibly above textfield";
row.value = @"Current value for the textfield";
[row setValueChanged:^{
DLog(@"New value: %@", row.value);
}];
[section addRow:row];

自定义单元格

这并不常见,但有时我不得不创建一个具有基本单元格不支持的某些内容的单元格。请放心,无需重写UITableView cellForRow dataSource方法。BlazeRow只需在完成块中简单地返回单元格,因此您可以随意自定义。

BlazeRow *row = [[BlazeRow alloc] initWithXibName:xibName];
[row setConfigureCell:^(UITableViewCell *cell) {
//Cast the row to your custom cell and customize all you need!        
}];

如果您创建自定义单元格,请勿忘记将您的单元格设置为 BlazeTableViewCell 的子类!

自定义部分标题或页脚

这些标题和页脚实际上与单元格的行为方式相同。您可以为任何自定义 XIB 创建任何内容,并简单地指向基类 BlazeTableHeaderFooterView。然后在代码创建部分时,可以设置 headerTitle、footerTitle、headerXibname 和 footerXibname。此外,如果有一个非常需要定制的自定义部分标题,它也可以像自定义单元格一样返回。

BlazeSection *section = [[BlazeSection alloc] initWithHeaderXibname:xibName];
[section setConfigureHeaderView:^(UITableViewHeaderFooterView *headerView) {
//Cast and customize!
}];

强大功能

创建这个框架后,我开始将它应用到每个应用中。当然,一段时间后,我发现了一些返回功能。显然,我必须在框架内部添加所有这些强大的功能!这样就可以消除更多样板代码了 :)

自动注册标题和单元格

通常,您必须使用以下行注册您所使用的每个自定义标题和单元格

[self.tableView registerNib:[UINib nibWithNibName:xibName bundle:nil] forCellReuseIdentifier:xibName];

但这已经不再是必须的!Blaze 可以自动检测您使用的单元格和标题,并为您注册它们!另一个节省时间的好方法!:)

动态添加/删除单元格

我希望我的表视图尽可能灵活,所以我创建了多个函数来快速使用动画添加/删除单元格。与使用索引不同,当您为行分配 ID 并使用这些 ID 动态添加/删除单元格时,它更易于阅读

[self addRow:row afterRowID:RowID withRowAnimation:UITableViewRowAnimationLeft];
[self removeRowWithID:RowID withRowAnimation:UITableViewRowAnimationRight];

自动值设置器(当使用CoreData时非常出色)

对于输入单元格,我开始使用完成块,将返回值设置为CoreData对象的值,如上所述的基本功能中所解释。但如果直接向行提供对象和属性名称,不是更容易吗?它可以自动更新对象而无需任何额外代码!您不需要提供当前值(因为它从给定的对象和属性名称中检索它),您可以删除完成块。只剩下一行了!

[row setAffectedObject:object affectedPropertyName:propertyName)];

如果您不希望硬编码属性名称以供修改,那么Blaze提供了Objective-C对象的类别,您可以使用如下方式

[row setAffectedObject:object affectedPropertyName:[object stringForPropertyName:@selector(name)]];

这样可以,编译器将警告您无法识别属性名称!

日期 & 选择视图

我想尽可能考虑多种输入类型,因此我创建了日期选择器和选择视图单元格。它们都以UITextField的输入视图实现。这样用户可以保持对键盘的关注,并快速提供他们的输入。当您有多个单元格和多种不同输入时,这尤其令人愉快。

自动输入字段上的下一个/上一个箭头

Blaze支持许多输入字段,它们始终使用键盘,因为我认为这是最用户友好的方式。因此,无论是文本、日期还是选择视图,用户都可以保持对键盘的关注。Blaze自动将带有左右侧的下一个/上一个箭头和右侧的'Done'按钮的InputAccessoryView添加到任何BlazeRow输入字段类型。用户可以使用这些箭头快速切换字段,无论这些字段是否位于不同的部分或不同的类型(日期、选择视图等)。

可拖动的缩放视图头

每个人都见过当您向下拖动时缩放的视图头视图。这是一个非常酷的效果,配置起来也不难。但是,如果使用频繁,就会变成样板代码。所以在Blaze中,您可以只需要一行代码就可以设置它! :)
只需简单地创建XIB,设置正确的约束,并使用这一行代码

self.zoomTableHeaderView = [[NSBundle mainBundle] loadNibNamed:@"ZoomHeaderView" owner:nil options:nil].firstObject;

空状态

您可能已经知道了非常棒的DZNEmptyDataSet cocoa pod,它可以帮助您轻松地在tableview中实现空状态。well,不用担心自己实现它,因为Blaze已经为您处理了这个问题!因此,您现在可以轻松地将图片、背景颜色、标题等作为属性放在您的BlazeTableViewController子类上。

动态行高选项

Blaze的整体理念是使用UITableViewCells并正确设置约束,以便tableview能够自动计算正确的高度,使用UITableViewAutomaticDimension。然而,如果您需要特定的行高,有三个选项

row.rowHeight = 30; //30 pixels high
row.rowHeightRatio = 0.3f; //30% of the total tableview's height
row.rowHeightDynamic = TRUE; //Calculates all other rowheights first and sets the remaining space to this row

下拉刷新

当然,Blaze支持UIRefreshControl。只需一行即可激活它,并使用完成块来了解用户何时想要刷新!

许多快速配置器

为了保持极致速度,Blaze提供了大量快速配置器,你可以在查看源文件时发现它们。例如,如果你在每个部分的每一行中使用相同的XIB文件,你只需简单地将BlazeSectionrowsXibname属性设置即可。比为每个BlazeRow键入相同的代码好得多。如果你为整个屏幕使用相同的xibName,只需简单地设置你的BlazeTableViewController子类的rowsXibName

有任何改进Blaze的惊人想法吗?

告诉我,发送拉取请求,或者你喜欢的任何方式!我自己为每个App中的每个屏幕都使用Blaze,我看不到自己会停止使用它的理由。所以我会尽力更新它,让它更加出色!

对于所使用的框架的致谢

DNZEmptyDataSet - 暂时不接受拉取请求,所以我已实现了文件而不是subspect。将来可能会改变这一点。