Automatically adjust content inset after view controller did layout subviews
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 267 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
|
@ -17,4 +17,13 @@
|
||||||
@property (nonatomic, assign, readwrite) UIEdgeInsets contentInset;
|
@property (nonatomic, assign, readwrite) UIEdgeInsets contentInset;
|
||||||
@property (nonatomic, assign, readwrite) BOOL automaticallyAdjustContentInsets;
|
@property (nonatomic, assign, readwrite) BOOL automaticallyAdjustContentInsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically adjusted content inset depends on view controller's top and bottom
|
||||||
|
* layout guides so if you've changed one of them (e.g. after rotation or manually) you should call this method
|
||||||
|
* to recalculate and refresh content inset.
|
||||||
|
* To handle case with changing navigation bar height call this method from viewDidLayoutSubviews:
|
||||||
|
* of your view controller.
|
||||||
|
*/
|
||||||
|
- (void)refreshContentInset;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -460,10 +460,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||||
_scrollView.frame = self.bounds;
|
_scrollView.frame = self.bounds;
|
||||||
_scrollView.contentOffset = originalOffset;
|
_scrollView.contentOffset = originalOffset;
|
||||||
|
|
||||||
[RCTView autoAdjustInsetsForView:self
|
|
||||||
withScrollView:_scrollView
|
|
||||||
updateOffset:YES];
|
|
||||||
|
|
||||||
[self updateClippedSubviews];
|
[self updateClippedSubviews];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +519,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||||
[_scrollView zoomToRect:rect animated:animated];
|
[_scrollView zoomToRect:rect animated:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)refreshContentInset
|
||||||
|
{
|
||||||
|
[RCTView autoAdjustInsetsForView:self
|
||||||
|
withScrollView:_scrollView
|
||||||
|
updateOffset:YES];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - ScrollView delegate
|
#pragma mark - ScrollView delegate
|
||||||
|
|
||||||
#define RCT_SCROLL_EVENT_HANDLER(delegateMethod, eventName) \
|
#define RCT_SCROLL_EVENT_HANDLER(delegateMethod, eventName) \
|
||||||
|
|
|
@ -95,9 +95,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||||
{
|
{
|
||||||
[super layoutSubviews];
|
[super layoutSubviews];
|
||||||
_webView.frame = self.bounds;
|
_webView.frame = self.bounds;
|
||||||
[RCTView autoAdjustInsetsForView:self
|
|
||||||
withScrollView:_webView.scrollView
|
|
||||||
updateOffset:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setContentInset:(UIEdgeInsets)contentInset
|
- (void)setContentInset:(UIEdgeInsets)contentInset
|
||||||
|
@ -133,6 +130,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)refreshContentInset
|
||||||
|
{
|
||||||
|
[RCTView autoAdjustInsetsForView:self
|
||||||
|
withScrollView:_webView.scrollView
|
||||||
|
updateOffset:YES];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - UIWebViewDelegate methods
|
#pragma mark - UIWebViewDelegate methods
|
||||||
|
|
||||||
- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
|
- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
|
||||||
|
|
|
@ -16,13 +16,15 @@
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "RCTViewControllerProtocol.h"
|
#import "RCTViewControllerProtocol.h"
|
||||||
#import "UIView+React.h"
|
#import "UIView+React.h"
|
||||||
|
#import "RCTAutoInsetsProtocol.h"
|
||||||
|
|
||||||
@implementation RCTWrapperViewController
|
@implementation RCTWrapperViewController
|
||||||
{
|
{
|
||||||
UIView *_wrapperView;
|
UIView *_wrapperView;
|
||||||
UIView *_contentView;
|
UIView *_contentView;
|
||||||
CGFloat _previousTopLayout;
|
RCTEventDispatcher *_eventDispatcher;
|
||||||
CGFloat _previousBottomLayout;
|
CGFloat _previousTopLayoutLength;
|
||||||
|
CGFloat _previousBottomLayoutLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize currentTopLayoutGuide = _currentTopLayoutGuide;
|
@synthesize currentTopLayoutGuide = _currentTopLayoutGuide;
|
||||||
|
@ -58,6 +60,32 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||||
_currentBottomLayoutGuide = self.bottomLayoutGuide;
|
_currentBottomLayoutGuide = self.bottomLayoutGuide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL RCTFindScrollViewAndRefreshContentInsetInView(UIView *view)
|
||||||
|
{
|
||||||
|
if ([view conformsToProtocol:@protocol(RCTAutoInsetsProtocol)]) {
|
||||||
|
[(id <RCTAutoInsetsProtocol>) view refreshContentInset];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
for (UIView *subview in view.subviews) {
|
||||||
|
if (RCTFindScrollViewAndRefreshContentInsetInView(subview)) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLayoutSubviews
|
||||||
|
{
|
||||||
|
[super viewDidLayoutSubviews];
|
||||||
|
|
||||||
|
if (_previousTopLayoutLength != _currentTopLayoutGuide.length ||
|
||||||
|
_previousBottomLayoutLength != _currentBottomLayoutGuide.length) {
|
||||||
|
RCTFindScrollViewAndRefreshContentInsetInView(_contentView);
|
||||||
|
_previousTopLayoutLength = _currentTopLayoutGuide.length;
|
||||||
|
_previousBottomLayoutLength = _currentBottomLayoutGuide.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static UIView *RCTFindNavBarShadowViewInView(UIView *view)
|
static UIView *RCTFindNavBarShadowViewInView(UIView *view)
|
||||||
{
|
{
|
||||||
if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1) {
|
if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1) {
|
||||||
|
|