Modular offset calculation
added sticky navigation feature added more tests BRIEF: Completely overhauled the offset implementation. Now, a "shyView" calculates it's position based on its parent maxY property. For the navigation bar, that would be the status bar. For the extension view, it would be the navigation bar.
This commit is contained in:
parent
0617cd18d4
commit
93402b62af
|
|
@ -53,6 +53,10 @@ This component helps you mimick the navigation bar auto scrolling that you see i
|
|||
|
||||

|
||||
|
||||
+ Sticky navigation bar (Thanks [@TiagoVeloso](https://github.com/TiagoVeloso) !)
|
||||
|
||||

|
||||
|
||||
+ Fade the entire navbar (Thanks [__@longsview__](https://github.com/longsview) !)
|
||||
|
||||

|
||||
|
|
|
|||
|
|
@ -52,7 +52,14 @@ typedef NS_ENUM(NSInteger, TLYShyNavBarFade) {
|
|||
*/
|
||||
@property (nonatomic, readonly) CGRect extensionViewBounds;
|
||||
|
||||
/* Sticky extension view
|
||||
/* Make the navigation bar stick to the top without collapsing
|
||||
* Deatuls to NO
|
||||
*/
|
||||
@property (nonatomic) BOOL stickyNavigationBar;
|
||||
|
||||
/* Make the extension view stick to the bottom of the navbar without
|
||||
* collapsing
|
||||
* Defaults to NO
|
||||
*/
|
||||
@property (nonatomic) BOOL stickyExtensionView;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,11 @@ static inline CGFloat AACStatusBarHeight(UIViewController *viewController)
|
|||
|
||||
UIView *view = viewController.view;
|
||||
CGRect frame = [view.superview convertRect:view.frame toView:view.window];
|
||||
|
||||
BOOL viewOverlapsStatusBar = frame.origin.y < statusBarHeight;
|
||||
if (!viewOverlapsStatusBar) {
|
||||
|
||||
if (!viewOverlapsStatusBar)
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +63,38 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface TLYShyStatusBarController : NSObject <TLYShyViewControllerParent>
|
||||
|
||||
@property (nonatomic, weak) UIViewController *viewController;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TLYShyStatusBarController
|
||||
|
||||
- (CGFloat)viewMaxY
|
||||
{
|
||||
CGFloat statusBarHeight = AACStatusBarHeight(self.viewController);
|
||||
/* The standard status bar is 20 pixels. The navigation bar extends 20 pixels up so it is overlapped by the status bar.
|
||||
* When there is a larger than 20 pixel status bar (e.g. a phone call is in progress or GPS is active), the center needs
|
||||
* to shift up 20 pixels to avoid this 'dead space' being visible above the usual nav bar.
|
||||
*/
|
||||
if (statusBarHeight > 20)
|
||||
{
|
||||
statusBarHeight -= 20;
|
||||
}
|
||||
|
||||
return statusBarHeight;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - TLYShyNavBarManager class
|
||||
|
||||
@interface TLYShyNavBarManager () <UIScrollViewDelegate>
|
||||
|
||||
@property (nonatomic, strong) id<TLYShyViewControllerParent> statusBarController;
|
||||
@property (nonatomic, strong) TLYShyViewController *navBarController;
|
||||
@property (nonatomic, strong) TLYShyViewController *extensionController;
|
||||
|
||||
|
|
@ -104,28 +135,10 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
self.previousScrollInsets = UIEdgeInsetsZero;
|
||||
self.previousYOffset = NAN;
|
||||
|
||||
self.navBarController = [[TLYShyViewController alloc] init];
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
|
||||
self.navBarController.expandedCenter = ^(UIView *view)
|
||||
{
|
||||
CGFloat statusBarHeight = AACStatusBarHeight(weakSelf.viewController);
|
||||
/* The standard status bar is 20 pixels. The navigation bar extends 20 pixels up so it is overlapped by the status bar.
|
||||
* When there is a larger than 20 pixel status bar (e.g. a phone call is in progress or GPS is active), the center needs
|
||||
* to shift up 20 pixels to avoid this 'dead space' being visible above the usual nav bar.
|
||||
*/
|
||||
if (statusBarHeight > 20)
|
||||
statusBarHeight -= 20;
|
||||
|
||||
return CGPointMake(CGRectGetMidX(view.bounds),
|
||||
CGRectGetMidY(view.bounds) + statusBarHeight);
|
||||
};
|
||||
self.statusBarController = [[TLYShyStatusBarController alloc] init];
|
||||
|
||||
self.navBarController.contractionAmount = ^(UIView *view)
|
||||
{
|
||||
return CGRectGetHeight(view.bounds);
|
||||
};
|
||||
self.navBarController = [[TLYShyViewController alloc] init];
|
||||
self.navBarController.parent = self.statusBarController;
|
||||
|
||||
self.extensionViewContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100.f, 0.f)];
|
||||
self.extensionViewContainer.backgroundColor = [UIColor clearColor];
|
||||
|
|
@ -133,17 +146,8 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
|
||||
self.extensionController = [[TLYShyViewController alloc] init];
|
||||
self.extensionController.view = self.extensionViewContainer;
|
||||
self.extensionController.contractionAmount = ^(UIView *view)
|
||||
{
|
||||
return CGRectGetHeight(view.bounds);
|
||||
};
|
||||
|
||||
self.extensionController.expandedCenter = ^(UIView *view)
|
||||
{
|
||||
return CGPointMake(CGRectGetMidX(view.bounds),
|
||||
CGRectGetMidY(view.bounds) + weakSelf.viewController.tly_topLayoutGuide.length);
|
||||
};
|
||||
|
||||
self.extensionController.parent = self.navBarController;
|
||||
|
||||
self.navBarController.child = self.extensionController;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
|
|
@ -234,13 +238,24 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)stickyNavigationBar
|
||||
{
|
||||
return self.navBarController.sticky;
|
||||
}
|
||||
|
||||
- (void)setStickyNavigationBar:(BOOL)stickyNavigationBar
|
||||
{
|
||||
self.navBarController.sticky = stickyNavigationBar;
|
||||
}
|
||||
|
||||
- (BOOL)stickyExtensionView
|
||||
{
|
||||
return self.extensionController.sticky;
|
||||
}
|
||||
|
||||
- (void)setStickyExtensionView:(BOOL)stickyExtensionView
|
||||
{
|
||||
_stickyExtensionView = stickyExtensionView;
|
||||
|
||||
if (self.navBarController) {
|
||||
self.navBarController.stickyExtensionView = _stickyExtensionView;
|
||||
}
|
||||
self.extensionController.sticky = stickyExtensionView;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -320,6 +335,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
// 6 - Update the navigation bar shyViewController
|
||||
self.navBarController.fadeBehavior = (TLYShyNavViewControllerFade)self.fadeBehavior;
|
||||
|
||||
|
||||
[self.navBarController updateYOffset:deltaY];
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +417,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage
|
|||
- (void)layoutViews
|
||||
{
|
||||
UIEdgeInsets scrollInsets = self.scrollView.contentInset;
|
||||
scrollInsets.top = CGRectGetHeight(self.extensionViewContainer.bounds) + self.viewController.tly_topLayoutGuide.length;
|
||||
scrollInsets.top = self.extensionController.viewMaxY;
|
||||
|
||||
if (UIEdgeInsetsEqualToEdgeInsets(scrollInsets, self.previousScrollInsets))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ typedef NS_ENUM(NSInteger, TLYShyNavViewControllerFade) {
|
|||
TLYShyNavViewControllerFadeNavbar,
|
||||
};
|
||||
|
||||
@protocol TLYShyViewControllerParent <NSObject>
|
||||
|
||||
@property (nonatomic, readonly) CGFloat viewMaxY;
|
||||
|
||||
@end
|
||||
|
||||
/* CLASS DESCRIPTION:
|
||||
* ==================
|
||||
* A shy view is a view that contracts when a scrolling event is
|
||||
|
|
@ -39,20 +45,19 @@ typedef NS_ENUM(NSInteger, TLYShyNavViewControllerFade) {
|
|||
@interface TLYShyViewController : NSObject
|
||||
|
||||
@property (nonatomic, weak) TLYShyViewController *child;
|
||||
@property (nonatomic, weak) id<TLYShyViewControllerParent> parent;
|
||||
@property (nonatomic, weak) UIView *view;
|
||||
|
||||
@property (nonatomic, copy) TLYShyViewControllerExpandedCenterBlock expandedCenter;
|
||||
@property (nonatomic, copy) TLYShyViewControllerContractionAmountBlock contractionAmount;
|
||||
|
||||
@property (nonatomic) TLYShyNavViewControllerFade fadeBehavior;
|
||||
|
||||
@property (nonatomic, readonly) CGFloat totalHeight;
|
||||
|
||||
/* Sticky extension view
|
||||
/* Sticky means it will always stay in expanded state
|
||||
*/
|
||||
@property (nonatomic) BOOL stickyExtensionView;
|
||||
@property (nonatomic) BOOL sticky;
|
||||
|
||||
- (CGFloat)updateYOffset:(CGFloat)deltaY;
|
||||
- (void)offsetCenterBy:(CGPoint)deltaPoint;
|
||||
|
||||
- (CGFloat)snap:(BOOL)contract;
|
||||
|
||||
|
|
@ -60,3 +65,7 @@ typedef NS_ENUM(NSInteger, TLYShyNavViewControllerFade) {
|
|||
- (CGFloat)contract;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface TLYShyViewController (AsParent) <TLYShyViewControllerParent>
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,16 @@
|
|||
|
||||
#import "TLYShyViewController.h"
|
||||
|
||||
const CGFloat contractionVelocity = 300.f;
|
||||
|
||||
@implementation TLYShyViewController (AsParent)
|
||||
|
||||
- (CGFloat)viewMaxY
|
||||
{
|
||||
return CGRectGetMaxY(self.view.frame);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface TLYShyViewController ()
|
||||
|
||||
|
|
@ -29,12 +38,17 @@ const CGFloat contractionVelocity = 300.f;
|
|||
// convenience
|
||||
- (CGPoint)expandedCenterValue
|
||||
{
|
||||
return self.expandedCenter(self.view);
|
||||
CGPoint center = CGPointMake(CGRectGetMidX(self.view.bounds),
|
||||
CGRectGetMidY(self.view.bounds));
|
||||
|
||||
center.y += self.parent.viewMaxY;
|
||||
|
||||
return center;
|
||||
}
|
||||
|
||||
- (CGFloat)contractionAmountValue
|
||||
{
|
||||
return self.contractionAmount(self.view);
|
||||
return self.sticky ? 0.f : CGRectGetHeight(self.view.bounds);
|
||||
}
|
||||
|
||||
- (CGPoint)contractedCenterValue
|
||||
|
|
@ -61,6 +75,13 @@ const CGFloat contractionVelocity = 300.f;
|
|||
|
||||
- (void)_onAlphaUpdate:(CGFloat)alpha
|
||||
{
|
||||
if (self.sticky)
|
||||
{
|
||||
self.view.alpha = 1.f;
|
||||
[self _updateSubviewsAlpha:1.f];
|
||||
return;
|
||||
}
|
||||
|
||||
switch (self.fadeBehavior) {
|
||||
|
||||
case TLYShyNavViewControllerFadeDisabled:
|
||||
|
|
@ -96,6 +117,15 @@ const CGFloat contractionVelocity = 300.f;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)_updateCenter:(CGPoint)newCenter
|
||||
{
|
||||
CGPoint currentCenter = self.view.center;
|
||||
CGPoint deltaPoint = CGPointMake(newCenter.x - currentCenter.x,
|
||||
newCenter.y - currentCenter.y);
|
||||
|
||||
[self offsetCenterBy:deltaPoint];
|
||||
}
|
||||
|
||||
#pragma mark - Public methods
|
||||
|
||||
- (void)setFadeBehavior:(TLYShyNavViewControllerFade)fadeBehavior
|
||||
|
|
@ -108,26 +138,26 @@ const CGFloat contractionVelocity = 300.f;
|
|||
}
|
||||
}
|
||||
|
||||
- (CGFloat)updateYOffset:(CGFloat)deltaY
|
||||
- (void)offsetCenterBy:(CGPoint)deltaPoint
|
||||
{
|
||||
if (self.child && deltaY < 0 && !self.stickyExtensionView)
|
||||
[self.child offsetCenterBy:deltaPoint];
|
||||
|
||||
self.view.center = CGPointMake(self.view.center.x + deltaPoint.x,
|
||||
self.view.center.y + deltaPoint.y);
|
||||
}
|
||||
|
||||
- (CGFloat)updateYOffset:(CGFloat)deltaY
|
||||
{
|
||||
if (self.child && deltaY < 0)
|
||||
{
|
||||
deltaY = [self.child updateYOffset:deltaY];
|
||||
self.child.view.hidden = deltaY < 0;
|
||||
self.child.view.hidden = (!self.child.sticky && deltaY < 0);
|
||||
}
|
||||
|
||||
CGFloat newYOffset = self.view.center.y + deltaY;
|
||||
CGFloat newYCenter = MAX(MIN(self.expandedCenterValue.y, newYOffset), self.contractedCenterValue.y);
|
||||
|
||||
self.view.center = CGPointMake(self.expandedCenterValue.x, newYCenter);
|
||||
|
||||
if (self.stickyExtensionView)
|
||||
{
|
||||
CGFloat newChildYOffset = self.child.view.center.y + deltaY;
|
||||
CGFloat newChildYCenter = MAX(MIN(self.child.expandedCenterValue.y, newChildYOffset), self.child.contractedCenterValue.y);
|
||||
|
||||
self.child.view.center = CGPointMake(self.child.expandedCenterValue.x, newChildYCenter);
|
||||
}
|
||||
[self _updateCenter:CGPointMake(self.expandedCenterValue.x, newYCenter)];
|
||||
|
||||
CGFloat newAlpha = 1.f - (self.expandedCenterValue.y - self.view.center.y) / self.contractionAmountValue;
|
||||
newAlpha = MIN(MAX(FLT_EPSILON, newAlpha), 1.f);
|
||||
|
|
@ -136,10 +166,14 @@ const CGFloat contractionVelocity = 300.f;
|
|||
|
||||
CGFloat residual = newYOffset - newYCenter;
|
||||
|
||||
if (self.child && deltaY > 0 && residual > 0 && !self.stickyExtensionView)
|
||||
if (self.child && deltaY > 0 && residual > 0)
|
||||
{
|
||||
residual = [self.child updateYOffset:residual];
|
||||
self.child.view.hidden = residual - (newYOffset - newYCenter) > FLT_EPSILON;
|
||||
self.child.view.hidden = (!self.child.sticky && residual - (newYOffset - newYCenter) > FLT_EPSILON);
|
||||
}
|
||||
else if (self.child.sticky && deltaY > 0)
|
||||
{
|
||||
[self.child updateYOffset:deltaY];
|
||||
}
|
||||
|
||||
return residual;
|
||||
|
|
@ -182,7 +216,7 @@ const CGFloat contractionVelocity = 300.f;
|
|||
|
||||
CGFloat amountToMove = self.expandedCenterValue.y - self.view.center.y;
|
||||
|
||||
self.view.center = self.expandedCenterValue;
|
||||
[self _updateCenter:self.expandedCenterValue];
|
||||
[self.child expand];
|
||||
|
||||
return amountToMove;
|
||||
|
|
@ -192,7 +226,7 @@ const CGFloat contractionVelocity = 300.f;
|
|||
{
|
||||
CGFloat amountToMove = self.contractedCenterValue.y - self.view.center.y;
|
||||
|
||||
self.view.center = self.contractedCenterValue;
|
||||
[self _updateCenter:self.contractedCenterValue];
|
||||
[self.child contract];
|
||||
|
||||
return amountToMove;
|
||||
|
|
|
|||
|
|
@ -86,9 +86,29 @@
|
|||
<segue destination="vXZ-lx-hvc" kind="push" id="iFx-zx-Yj8"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="1" textLabel="WdW-Lh-Cfs" style="IBUITableViewCellStyleDefault" id="TTx-eK-xUp">
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="1" textLabel="2GL-4f-xic" style="IBUITableViewCellStyleDefault" id="dRT-27-ySW">
|
||||
<rect key="frame" x="0.0" y="130" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dRT-27-ySW" id="cDy-Ba-zBy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="287" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="No Extension View Test" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2GL-4f-xic">
|
||||
<rect key="frame" x="15" y="0.0" width="270" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="Vir-3r-RAn" kind="push" id="8Qt-p1-3tA"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="2" textLabel="WdW-Lh-Cfs" style="IBUITableViewCellStyleDefault" id="TTx-eK-xUp">
|
||||
<rect key="frame" x="0.0" y="174" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="TTx-eK-xUp" id="N2A-N5-eQc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="287" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
|
@ -106,8 +126,28 @@
|
|||
<segue destination="K7e-Au-F1w" kind="push" id="BJ5-fT-FrY"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="2" textLabel="7pe-uQ-9XE" style="IBUITableViewCellStyleDefault" id="CJy-qF-mnS">
|
||||
<rect key="frame" x="0.0" y="174" width="320" height="44"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="3" textLabel="WIt-Sx-VLk" style="IBUITableViewCellStyleDefault" id="0y3-Aj-VEQ">
|
||||
<rect key="frame" x="0.0" y="218" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="0y3-Aj-VEQ" id="w1B-en-E0m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="287" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Sticky Navbar Test" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="WIt-Sx-VLk">
|
||||
<rect key="frame" x="15" y="0.0" width="270" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="7f1-kX-LN4" kind="push" id="YcG-cM-tuL"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="4" textLabel="7pe-uQ-9XE" style="IBUITableViewCellStyleDefault" id="CJy-qF-mnS">
|
||||
<rect key="frame" x="0.0" y="262" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="CJy-qF-mnS" id="nYc-co-8cU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="287" height="43.5"/>
|
||||
|
|
@ -126,8 +166,8 @@
|
|||
<segue destination="YrI-BX-jJR" kind="push" id="6AH-6S-diz"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="3" textLabel="qz8-f8-ztz" style="IBUITableViewCellStyleDefault" id="cog-xO-RM8">
|
||||
<rect key="frame" x="0.0" y="218" width="320" height="44"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="5" textLabel="qz8-f8-ztz" style="IBUITableViewCellStyleDefault" id="cog-xO-RM8">
|
||||
<rect key="frame" x="0.0" y="306" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="cog-xO-RM8" id="bqe-Oi-QQK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
|
||||
|
|
@ -143,8 +183,8 @@
|
|||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="4" textLabel="JCj-eZ-ePK" style="IBUITableViewCellStyleDefault" id="lDx-31-RTM">
|
||||
<rect key="frame" x="0.0" y="262" width="320" height="44"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="6" textLabel="JCj-eZ-ePK" style="IBUITableViewCellStyleDefault" id="lDx-31-RTM">
|
||||
<rect key="frame" x="0.0" y="350" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="lDx-31-RTM" id="Pch-9t-ngw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
|
||||
|
|
@ -241,7 +281,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="PDI-vm-1dr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="371" y="-532"/>
|
||||
<point key="canvasLocation" x="783" y="-532"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="WAx-ee-jTN">
|
||||
|
|
@ -301,13 +341,129 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="-1" y="208"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="zcE-h0-aq3">
|
||||
<objects>
|
||||
<viewController id="7f1-kX-LN4" customClass="TLYViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="pUV-UO-fri"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="POi-6q-Jdv"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="eOj-4e-h2Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p6u-pz-ec0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="sample" translatesAutoresizingMaskIntoConstraints="NO" id="iiY-8B-e2T">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="800"/>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Sz2-8s-bu4">
|
||||
<rect key="frame" x="35" y="201" width="250" height="35"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="19"/>
|
||||
<state key="normal" title="Push View Controller">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<segue destination="7f1-kX-LN4" kind="push" id="WRD-ac-CcU"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="7f1-kX-LN4" id="Em9-iO-CRq"/>
|
||||
</connections>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="p6u-pz-ec0" firstAttribute="top" secondItem="pUV-UO-fri" secondAttribute="bottom" constant="-64" id="A23-5t-IBv"/>
|
||||
<constraint firstItem="POi-6q-Jdv" firstAttribute="bottom" secondItem="p6u-pz-ec0" secondAttribute="bottom" id="Jo6-Mp-8tk"/>
|
||||
<constraint firstItem="p6u-pz-ec0" firstAttribute="leading" secondItem="eOj-4e-h2Z" secondAttribute="leading" id="MTL-4R-N3X"/>
|
||||
<constraint firstAttribute="trailing" secondItem="p6u-pz-ec0" secondAttribute="trailing" id="N2z-x2-V6b"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="VGK-r1-atg"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="stickyExtensionView" value="NO"/>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fadeBehavior">
|
||||
<integer key="value" value="1"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="stickyNavigationBar" value="YES"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="iiY-8B-e2T" id="lSi-xq-DXH"/>
|
||||
<outlet property="scrollView" destination="p6u-pz-ec0" id="jPl-rq-FFo"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Wqb-OT-maY" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="363" y="208"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="bYR-xs-cnr">
|
||||
<objects>
|
||||
<viewController id="Vir-3r-RAn" customClass="TLYViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="BkE-Iq-z6J"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="8Is-wZ-9BQ"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="0Ja-Wx-zy2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gDa-ud-MJA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="sample" translatesAutoresizingMaskIntoConstraints="NO" id="53M-22-p92">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="800"/>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vdy-g9-wQL">
|
||||
<rect key="frame" x="35" y="201" width="250" height="35"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="19"/>
|
||||
<state key="normal" title="Push View Controller">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<segue destination="Vir-3r-RAn" kind="push" id="fbQ-WQ-fvM"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Vir-3r-RAn" id="zC7-46-HJO"/>
|
||||
</connections>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="gDa-ud-MJA" secondAttribute="trailing" id="0pa-sw-lVw"/>
|
||||
<constraint firstItem="8Is-wZ-9BQ" firstAttribute="bottom" secondItem="gDa-ud-MJA" secondAttribute="bottom" id="T0T-Y0-yyw"/>
|
||||
<constraint firstItem="gDa-ud-MJA" firstAttribute="top" secondItem="BkE-Iq-z6J" secondAttribute="bottom" constant="-64" id="WcX-jW-FEV"/>
|
||||
<constraint firstItem="gDa-ud-MJA" firstAttribute="leading" secondItem="0Ja-Wx-zy2" secondAttribute="leading" id="s51-Ms-zqo"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="ocA-JK-sul"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="disableExtensionView" value="YES"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="53M-22-p92" id="uxa-AD-vUc"/>
|
||||
<outlet property="scrollView" destination="gDa-ud-MJA" id="w2M-m2-Cbo"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="W0g-zW-htj" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="363" y="-532"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="sample" width="320" height="800"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="6AH-6S-diz"/>
|
||||
<segue reference="BJ5-fT-FrY"/>
|
||||
<segue reference="iFx-zx-Yj8"/>
|
||||
<segue reference="YcG-cM-tuL"/>
|
||||
<segue reference="6AH-6S-diz"/>
|
||||
<segue reference="8Qt-p1-3tA"/>
|
||||
<segue reference="BJ5-fT-FrY"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -29,16 +29,13 @@
|
|||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return 5;
|
||||
return 7;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSString *cellId = [@(indexPath.row) stringValue];
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId
|
||||
forIndexPath:indexPath];
|
||||
|
||||
return cell;
|
||||
return [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
@interface TLYViewController ()
|
||||
|
||||
/* we set this in the xib as a runtime property */
|
||||
@property (nonatomic, assign) IBInspectable BOOL disableExtensionView;
|
||||
@property (nonatomic, assign) IBInspectable BOOL stickyNavigationBar;
|
||||
@property (nonatomic, assign) IBInspectable BOOL stickyExtensionView;
|
||||
@property (nonatomic, assign) IBInspectable NSInteger fadeBehavior;
|
||||
|
||||
|
|
@ -26,6 +27,9 @@
|
|||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
|
||||
self.disableExtensionView = NO;
|
||||
self.stickyNavigationBar = NO;
|
||||
self.stickyExtensionView = NO;
|
||||
self.fadeBehavior = TLYShyNavBarFadeSubviews;
|
||||
|
||||
self.title = @"WTFox Say";
|
||||
|
|
@ -37,13 +41,20 @@
|
|||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 44.f)];
|
||||
view.backgroundColor = [UIColor redColor];
|
||||
UIView *view = nil;
|
||||
|
||||
if (!self.disableExtensionView)
|
||||
{
|
||||
view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 44.f)];
|
||||
view.backgroundColor = [UIColor redColor];
|
||||
}
|
||||
|
||||
/* Library code */
|
||||
self.shyNavBarManager.scrollView = self.scrollView;
|
||||
/* Can then be remove by setting the ExtensionView to nil */
|
||||
[self.shyNavBarManager setExtensionView:view];
|
||||
/* Make navbar stick to the top */
|
||||
[self.shyNavBarManager setStickyNavigationBar:self.stickyNavigationBar];
|
||||
/* Make the extension view stick to the top */
|
||||
[self.shyNavBarManager setStickyExtensionView:self.stickyExtensionView];
|
||||
/* Navigation bar fade behavior */
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 433 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 36 KiB |
Loading…
Reference in New Issue