BLKFlexibleHeightBar
允许您创建具有灵活高度的头部栏。通常,这种界面范式用于隐藏控件,在用户滚动时为更多内容腾出空间。这在第三方应用,如 Facebook 和 Square Cash,以及第一方应用,如 Safari 中都可以看到。
BLKFlexibleHeightBar
可以根据需要进行栏的创建和操作
由于这个库模块化和可扩展的特性,您不受单一外观或单一感觉的限制。如同 UICollectionView 用于显示数据集合,BLKFlexibleHeightBar
用于创建头部栏。
栏的高度不是通过调整框架来直接设置的。相反,通过设置栏的 progress
属性来进行高度调整。进度属性表示栏从最大高度缩小到最小高度的程度。
progress == 0.0
表示栏处于最大高度。progress == 0.5
表示栏处于最大高度和最小高度之间。progress == 1.0
表示栏处于最小高度。一个好的起点是创建一个带有某些滚动视图的项目(例如,UITableView、UICollectionView、UIWebView、UIScrollView等)。确保您已经设置了一个属性来访问您的滚动视图,因为我们稍后需要设置其代理属性。
首先,将主BLKFlexibleHeightBar
头文件导入到您将配置栏的类中。
#import "BLKFlexibleHeightBar.h"
接下来,创建一个BLKFlexibleHeightBar
的实例并对其进行配置。当我们调用initWithFrame:
时,栏的maximumBarHeight
属性将自动设置为框架的高度。我们可以手动将minimumBarHeight
从其默认值20.0设置。最后,我们可以给它一个颜色并将我们的栏添加到视图层次结构中。
BLKFlexibleHeightBar *myBar = [[BLKFlexibleHeightBar alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 100.0)];
myBar.minimumBarHeight = 50.0;
myBar.backgroundColor = [UIColor colorWithRed:0.86 green:0.25 blue:0.23 alpha:1];
[self.view addSubview:myBar];
现在我们有一个没有子视图和没有行为,但定义了最大高度和最小高度的栏。
为了给栏一个行为,我们可以使用其中的一种包含的行为。Square Cash的栏行为非常容易理解。当滚动到顶部时,栏在最大高度。当用户向下滚动时,栏开始隐藏。使栏再次可见的唯一方法是滚动到顶部。
#import "SquareCashStyleBehaviorDefiner.h"
SquareCashStyleBehaviorDefiner
(继承自BLKFlexibleHeightBarBehaviorDefiner
)包含了控制栏高度何时以及如何变化的全部逻辑。
将myBar
的behaviorDefiner
属性设置为SquareCashStyleBehaviorDefiner
的一个实例。
myBar.behaviorDefiner = [SquareCashStyleBehaviorDefiner new];
BLKFlexibleHeightBarBehaviorDefiner
的行为直接依赖于我们的滚动视图的状态。因此,BLKFlexibleHeightBarBehaviorDefiner
(当然,以及它的所有子类)符合UIScrollViewDelegate
。
将您的滚动视图的UIScrollView
代理属性设置为myBar
的behaviorDefiner
属性(如果需要,可以进行转型)。这给了我们的行为定义者从我们的滚动视图中需要的信息,以便正确控制栏的高度。
self.tableView.delegate = (id<UITableViewDelegate>)myBar.behaviorDefiner;
吸附会强制您的栏在用户停止滚动时动画到最终位置。任何BLKFlexibleHeightBarBehaviorDefiner
的子类都会免费获得吸附功能。吸附通过定义一个最终的栏progress
值来实现,该值将在用户停止滚动并且栏在某个进度值范围内时进行动画。
[myBar.behaviorDefiner addSnappingPositionProgress:0.0 forProgressRangeStart:0.0 end:0.5];
[myBar.behaviorDefiner addSnappingPositionProgress:1.0 forProgressRangeStart:0.5 end:1.0];
上述代码会简单地使栏在progress == 0.0
(最大高度)或progress == 1.0
(最小高度)之间吸附,取决于哪一个更接近。可以定义其他吸附位置,不一定必须遵循“最接近的那个”规则。
BLKFlexibleHeightBar
实例的子视图定义了对于关键的progress
值的布局属性(例如,帧、alpha、transform等)。
在progress == 0.0
(最大栏高度)时,您的子视图可以具有alpha == 1.0
。
在progress == 1.0
(最小栏高度)时,您的子视图可以具有alpha == 0.0
和transform == CGAffineTransformMakeScale(0.2, 0.2)
。
当栏从最大高度压缩到最小高度时,您的子视图将平滑地缩小并淡出。
首先创建并添加一个子视图到您的栏中。不必担心给它一个框架 - 下一步定义的布局属性将确定其外观和位置。
UILabel *label = [[UILabel alloc] init];
label.text = @"TrendyStartup.io";
label.font = [UIFont systemFontOfSize:25.0];
label.textColor = [UIColor whiteColor];
[label sizeToFit];
[myBar addSubview:label];
接下来,我们将为子视图的所有离散布局状态配置布局属性。对于本例,我们希望标签随着条形缩小时渐变、缩小并向上滑动,当条形完全收缩时完全消失。我们需要为子视图定义2个离散状态——初始状态,此时子视图完全可见且全尺寸;最终状态,此时子视图消失且不再可见。所有中间状态都将自动填充,并实现平滑过渡。
我们通过定义子视图的布局属性,使用BLKFlexibleHeightBarSubviewLayoutAttributes
类来定义这些离散布局状态。
BLKFlexibleHeightBarSubviewLayoutAttributes *initialLayoutAttributes = [BLKFlexibleHeightBarSubviewLayoutAttributes new];
initialLayoutAttributes.size = label.frame.size;
initialLayoutAttributes.center = CGPointMake(CGRectGetMidX(myBar.bounds), CGRectGetMidY(myBar.bounds)+10.0);
// This is what we want the bar to look like at its maximum height (progress == 0.0)
[label addLayoutAttributes:initialLayoutAttributes forProgress:0.0];
然后
// Create a final set of layout attributes based on the same values as the initial layout attributes
BLKFlexibleHeightBarSubviewLayoutAttributes *finalLayoutAttributes = [[BLKFlexibleHeightBarSubviewLayoutAttributes alloc] initWithExistingLayoutAttributes:initialLayoutAttributes];
finalLayoutAttributes.alpha = 0.0;
CGAffineTransform translation = CGAffineTransformMakeTranslation(0.0, -30.0);
CGAffineTransform scale = CGAffineTransformMakeScale(0.2, 0.2);
finalLayoutAttributes.transform = CGAffineTransformConcat(scale, translation);
// This is what we want the bar to look like at its minimum height (progress == 1.0)
[label addLayoutAttributes:finalLayoutAttributes forProgress:1.0];
可以以相同的方式添加更多布局属性和子视图,使您能够创建几乎任何可想象的灵活条形设计。
如果提供的任何行为定义器不符合您应用的需求,创建自己的自定义行为定义器可能是个不错的选择。
为了支持任何类型的行为,BLKFlexibleHeightBar
被设计为一个易于插件和用法的条形行为架构。通过从BLKFlexibleHeightBarBehaviorDefiner
派生,开发人员可以完全控制条形的progress
属性(因此,高度)何时以及如何更新。
BLKFlexibleHeightBarBehaviorDefiner
需要派生才能使用。本身,它只提供捕捉功能和一个控制条形在达到最大高度时是否弹跳的属性。它不会尝试在滚动时调整条形的高度。首先创建一个派生的BLKFlexibleHeightBarBehaviorDefiner
子类。
定义器的基本模式如下
UIScrollViewDelegate
协议方法。-scrollViewDidScroll:
通常是一个有用的起点。-scrollViewDidScroll:
中的当前滚动位置,为行为定义器的flexibleHeightBar
属性计算一个新的进度值。将会有用,去询问flexibleHeightBar
的maximumBarHeight
和minimumBarHeight
属性。self.flexibleHeightBar.progress
设置为第2步中计算出的值。[self.flexibleHeightBar setNeedsLayout]
通知行为定义器的flexibleHeightBar
它需要重新布局。在-scrollViewDidScroll:
之外进行其他计算可能很有用。例如,包含的FacebookStyleBehaviorDefiner
需要在条形隐藏或显示之前应用滚动阈值。此计算在-scrollViewWillBeginDragging:
中进行。
SafariStyleBehaviorDefiner
(使用速度而不是仅滚动位置)。Auto Layout
的布局属性将简化一些复杂的条形设计,消除在定义布局属性时自己执行最终帧和大小计算的必要性。您可以通过Twitter @BKyourway19联系我