[ASDisplayNode] Provide safeAreaInsets and layoutMargins bridge (#685)

* [ASDisplayNode] Add safeAreaInsets, layoutMargins and related properties to ASDisplayNode

* Add layoutMargins bridged to the underlying view

* Add safeAreaInsets bridged to the underlying view

* Add fallback calculation of safeAreaInsets for old iOS versions

* Add automaticallyRelayoutOnSafeAreaChanges and automaticallyRelayoutOnLayoutMarginsChanges properties

* Add additionalSafeAreaInsets property to ASViewController for compatibility with old iOS versions

* Provide safeAreaInsets for layer-backed nodes.

This also fixes tests.

* Fix crash when insetsLayoutMarginsFromSafeArea is set from a background thread

* Changes requested at code review:
* Update documentation for layoutMargins and safeAreaInsets properties. Suggest that users set the automaticallyRelayout* flags to ensure that their layout is synchronized to the margin's values.
* Fix accessing ASDisplayNode internal structures without a lock.
* Add shortcut in -[ASDisplayNode _fallbackUpdateSafeAreaOnChildren] to skip a child when possible.
* Add shortcut in ASViewController to avoid fallback safe area insets recalculation in iOS 11. Fix fallback safe area insets recalculation when the additionalSafeAreaInsets are set.
* Add debug check that a view controller's node is never reused without its view controller, so the viewControllerRoot flag value is always consistent.
* Use getters instead of reading ivars directly in -layoutMarginsDidChange and -safeAreaInsetsDidChange.

* Minor change in CHANGELOG

* Minor change in ASDisplayNodeTests.mm
This commit is contained in:
Yevgen Pogribnyi
2018-03-27 16:29:17 +03:00
committed by Huy Nguyen
parent 063194cb1d
commit 7f01b89ddc
13 changed files with 485 additions and 3 deletions

View File

@@ -551,6 +551,20 @@ extern NSInteger const ASDefaultDrawingPriority;
*/
@property (nonatomic, readonly) BOOL supportsLayerBacking;
/**
* Whether or not the node layout should be automatically updated when it receives safeAreaInsetsDidChange.
*
* Defaults to NO.
*/
@property (nonatomic, assign) BOOL automaticallyRelayoutOnSafeAreaChanges;
/**
* Whether or not the node layout should be automatically updated when it receives layoutMarginsDidChange.
*
* Defaults to NO.
*/
@property (nonatomic, assign) BOOL automaticallyRelayoutOnLayoutMarginsChanges;
@end
/**
@@ -725,6 +739,33 @@ extern NSInteger const ASDefaultDrawingPriority;
@property (nonatomic, assign) BOOL autoresizesSubviews; // default==YES (undefined for layer-backed nodes)
@property (nonatomic, assign) UIViewAutoresizing autoresizingMask; // default==UIViewAutoresizingNone (undefined for layer-backed nodes)
/**
* @abstract Content margins
*
* @discussion This property is bridged to its UIView counterpart.
*
* If your layout depends on this property, you should probably enable automaticallyRelayoutOnLayoutMarginsChanges to ensure
* that the layout gets automatically updated when the value of this property changes. Or you can override layoutMarginsDidChange
* and make all the necessary updates manually.
*/
@property (nonatomic, assign) UIEdgeInsets layoutMargins;
@property (nonatomic, assign) BOOL preservesSuperviewLayoutMargins; // default is NO - set to enable pass-through or cascading behavior of margins from this views parent to its children
- (void)layoutMarginsDidChange;
/**
* @abstract Safe area insets
*
* @discussion This property is bridged to its UIVIew counterpart.
*
* If your layout depends on this property, you should probably enable automaticallyRelayoutOnSafeAreaChanges to ensure
* that the layout gets automatically updated when the value of this property changes. Or you can override safeAreaInsetsDidChange
* and make all the necessary updates manually.
*/
@property (nonatomic, readonly) UIEdgeInsets safeAreaInsets;
@property (nonatomic, assign) BOOL insetsLayoutMarginsFromSafeArea; // Default: YES
- (void)safeAreaInsetsDidChange;
// UIResponder methods
// By default these fall through to the underlying view, but can be overridden.
- (BOOL)canBecomeFirstResponder; // default==NO