Browse Source

Options resolving refactor (#4105)

* bind viewController to presenters using bindViewController

* Merge options to the specific provided layout

* Moved custom titleView creation to RNNRootViewController

* Moved default options to presenters, moved options applying to presenters, resolved options in RNNOptionsResolver

* Fixes merge options

* Fixes topBar transition on pop

* Prevent titleView creation when react titleView exists

* Fixed unit tests

* Options refactor WIP

* Detach applied options from DTO - WIP

* Added option types and option parsers

* Unit test passes

* Added presenters for each parent type

* Fixes unit tests

* Rename StringParam to Text, changed bottomTabs.drawBehind and topBar.drawBehind default to false

* set layout.backgroundColor default to white

* Added unit tests for RNNViewControllerPresenter

* Set layout.backgroundColor default nil

* Fixes buttons color missing options

* Fix unit test

* fix button color parsing

* Moved default options to presenters

* default options fixes

* Fixes e2e

* Fixes unit tests

* Resolve child options on childWillAppear

* Recrusively setDefaultOptions on rootViewController tree

* Fixes default values

* Fixes tests
Yogev Ben David 5 years ago
parent
commit
2afbfd6e67
No account linked to committer's email address
100 changed files with 1367 additions and 784 deletions
  1. 11
    0
      lib/ios/Bool.h
  2. 27
    0
      lib/ios/Bool.m
  3. 8
    0
      lib/ios/BoolParser.h
  4. 10
    0
      lib/ios/BoolParser.m
  5. 12
    0
      lib/ios/Color.h
  6. 23
    0
      lib/ios/Color.m
  7. 8
    0
      lib/ios/ColorParser.h
  8. 11
    0
      lib/ios/ColorParser.m
  9. 5
    0
      lib/ios/Dictionary.h
  10. 11
    0
      lib/ios/Dictionary.m
  11. 8
    0
      lib/ios/DictionaryParser.h
  12. 10
    0
      lib/ios/DictionaryParser.m
  13. 9
    0
      lib/ios/Double.h
  14. 25
    0
      lib/ios/Double.m
  15. 8
    0
      lib/ios/DoubleParser.h
  16. 10
    0
      lib/ios/DoubleParser.m
  17. 10
    0
      lib/ios/Image.h
  18. 19
    0
      lib/ios/Image.m
  19. 8
    0
      lib/ios/ImageParser.h
  20. 11
    0
      lib/ios/ImageParser.m
  21. 9
    0
      lib/ios/IntNumber.h
  22. 25
    0
      lib/ios/IntNumber.m
  23. 8
    0
      lib/ios/IntNumberParser.h
  24. 10
    0
      lib/ios/IntNumberParser.m
  25. 5
    0
      lib/ios/NullBool.h
  26. 11
    0
      lib/ios/NullBool.m
  27. 5
    0
      lib/ios/NullColor.h
  28. 10
    0
      lib/ios/NullColor.m
  29. 5
    0
      lib/ios/NullDictionary.h
  30. 10
    0
      lib/ios/NullDictionary.m
  31. 5
    0
      lib/ios/NullDouble.h
  32. 11
    0
      lib/ios/NullDouble.m
  33. 5
    0
      lib/ios/NullImage.h
  34. 11
    0
      lib/ios/NullImage.m
  35. 5
    0
      lib/ios/NullIntNumber.h
  36. 12
    0
      lib/ios/NullIntNumber.m
  37. 5
    0
      lib/ios/NullNumber.h
  38. 10
    0
      lib/ios/NullNumber.m
  39. 5
    0
      lib/ios/NullText.h
  40. 10
    0
      lib/ios/NullText.m
  41. 11
    0
      lib/ios/Number.h
  42. 19
    0
      lib/ios/Number.m
  43. 8
    0
      lib/ios/NumberParser.h
  44. 10
    0
      lib/ios/NumberParser.m
  45. 15
    0
      lib/ios/Param.h
  46. 46
    0
      lib/ios/Param.m
  47. 8
    1
      lib/ios/RNNAnimationOptions.m
  48. 6
    6
      lib/ios/RNNBackButtonOptions.h
  49. 10
    44
      lib/ios/RNNBackButtonOptions.m
  50. 4
    4
      lib/ios/RNNBackgroundOptions.h
  51. 8
    90
      lib/ios/RNNBackgroundOptions.m
  52. 13
    3
      lib/ios/RNNBasePresenter.h
  53. 31
    4
      lib/ios/RNNBasePresenter.m
  54. 14
    14
      lib/ios/RNNBottomTabOptions.h
  55. 19
    136
      lib/ios/RNNBottomTabOptions.m
  56. 11
    0
      lib/ios/RNNBottomTabPresenter.h
  57. 33
    0
      lib/ios/RNNBottomTabPresenter.m
  58. 13
    13
      lib/ios/RNNBottomTabsOptions.h
  59. 16
    66
      lib/ios/RNNBottomTabsOptions.m
  60. 7
    7
      lib/ios/RNNButtonOptions.h
  61. 15
    0
      lib/ios/RNNButtonOptions.m
  62. 27
    15
      lib/ios/RNNCommandsHandler.m
  63. 3
    3
      lib/ios/RNNComponentOptions.h
  64. 10
    0
      lib/ios/RNNComponentOptions.m
  65. 2
    2
      lib/ios/RNNControllerFactory.h
  66. 26
    16
      lib/ios/RNNControllerFactory.m
  67. 8
    0
      lib/ios/RNNDefaultOptionsHelper.h
  68. 18
    0
      lib/ios/RNNDefaultOptionsHelper.m
  69. 8
    0
      lib/ios/RNNFontAttributesCreator.h
  70. 25
    0
      lib/ios/RNNFontAttributesCreator.m
  71. 5
    4
      lib/ios/RNNLargeTitleOptions.h
  72. 7
    40
      lib/ios/RNNLargeTitleOptions.m
  73. 0
    1
      lib/ios/RNNLayoutInfo.h
  74. 1
    1
      lib/ios/RNNLayoutOptions.h
  75. 8
    5
      lib/ios/RNNLayoutOptions.m
  76. 6
    2
      lib/ios/RNNLayoutProtocol.h
  77. 0
    2
      lib/ios/RNNLeafProtocol.h
  78. 2
    2
      lib/ios/RNNModalManager.m
  79. 12
    12
      lib/ios/RNNNavigationButtons.m
  80. 3
    0
      lib/ios/RNNNavigationController.h
  81. 88
    8
      lib/ios/RNNNavigationController.m
  82. 0
    2
      lib/ios/RNNNavigationControllerPresenter.h
  83. 87
    4
      lib/ios/RNNNavigationControllerPresenter.m
  84. 11
    7
      lib/ios/RNNNavigationOptions.h
  85. 33
    57
      lib/ios/RNNNavigationOptions.m
  86. 13
    20
      lib/ios/RNNOptions.h
  87. 17
    60
      lib/ios/RNNOptions.m
  88. 0
    10
      lib/ios/RNNOptionsManager.h
  89. 0
    12
      lib/ios/RNNOptionsManager.m
  90. 1
    1
      lib/ios/RNNOverlayOptions.h
  91. 12
    4
      lib/ios/RNNOverlayOptions.m
  92. 2
    0
      lib/ios/RNNParentProtocol.h
  93. 1
    1
      lib/ios/RNNReactRootViewCreator.m
  94. 0
    2
      lib/ios/RNNRootViewController.h
  95. 71
    43
      lib/ios/RNNRootViewController.m
  96. 2
    2
      lib/ios/RNNSideMenuChildVC.h
  97. 30
    13
      lib/ios/RNNSideMenuChildVC.m
  98. 5
    13
      lib/ios/RNNSideMenuController.h
  99. 85
    32
      lib/ios/RNNSideMenuController.m
  100. 0
    0
      lib/ios/RNNSideMenuOptions.h

+ 11
- 0
lib/ios/Bool.h View File

@@ -0,0 +1,11 @@
1
+#import "Param.h"
2
+
3
+@interface Bool : Param
4
+
5
+- (BOOL)get;
6
+
7
+- (NSNumber *)getValue;
8
+
9
+- (BOOL)getWithDefaultValue:(BOOL)value;
10
+
11
+@end

+ 27
- 0
lib/ios/Bool.m View File

@@ -0,0 +1,27 @@
1
+#import "Bool.h"
2
+
3
+@interface Bool()
4
+
5
+@property (nonatomic, retain) NSNumber* value;
6
+
7
+@end
8
+
9
+@implementation Bool
10
+
11
+- (BOOL)get {
12
+	return [self.value boolValue];
13
+}
14
+
15
+- (NSNumber *)getValue {
16
+	return self.value;
17
+}
18
+
19
+- (BOOL)getWithDefaultValue:(BOOL)defaultValue {
20
+	if (self.value) {
21
+		return [self.value boolValue];
22
+	} else {
23
+		return defaultValue;
24
+	}
25
+}
26
+
27
+@end

+ 8
- 0
lib/ios/BoolParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Bool.h"
3
+
4
+@interface BoolParser : NSObject
5
+
6
++ (Bool *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 10
- 0
lib/ios/BoolParser.m View File

@@ -0,0 +1,10 @@
1
+#import "BoolParser.h"
2
+#import "NullBool.h"
3
+
4
+@implementation BoolParser
5
+
6
++ (Bool *)parse:(NSDictionary *)json key:(NSString *)key {
7
+	return json[key] ? [[Bool alloc] initWithValue:json[key]] : [NullBool new];
8
+}
9
+
10
+@end

+ 12
- 0
lib/ios/Color.h View File

@@ -0,0 +1,12 @@
1
+#import "Param.h"
2
+#import <UIKit/UIKit.h>
3
+
4
+@interface Color : Param
5
+
6
+- (instancetype)initWithValue:(UIColor *)value;
7
+
8
+- (UIColor *)get;
9
+
10
+- (UIColor *)getWithDefaultValue:(id)defaultValue;
11
+
12
+@end

+ 23
- 0
lib/ios/Color.m View File

@@ -0,0 +1,23 @@
1
+#import "Color.h"
2
+
3
+@interface Color()
4
+
5
+@property (nonatomic, retain) UIColor* value;
6
+
7
+@end
8
+
9
+@implementation Color
10
+
11
+- (instancetype)initWithValue:(UIColor *)value {
12
+	return [super initWithValue:value];
13
+}
14
+
15
+- (UIColor *)get {
16
+	return self.value;
17
+}
18
+
19
+- (UIColor *)getWithDefaultValue:(id)defaultValue {
20
+	return [super getWithDefaultValue:defaultValue];
21
+}
22
+
23
+@end

+ 8
- 0
lib/ios/ColorParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Color.h"
3
+
4
+@interface ColorParser : NSObject
5
+
6
++ (Color *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 11
- 0
lib/ios/ColorParser.m View File

@@ -0,0 +1,11 @@
1
+#import "ColorParser.h"
2
+#import "NullColor.h"
3
+#import <React/RCTConvert.h>
4
+
5
+@implementation ColorParser
6
+
7
++ (Color *)parse:(NSDictionary *)json key:(NSString *)key {
8
+	return json[key] ? [[Color alloc] initWithValue:[RCTConvert UIColor:json[key]]] : [NullColor new];
9
+}
10
+
11
+@end

+ 5
- 0
lib/ios/Dictionary.h View File

@@ -0,0 +1,5 @@
1
+#import "Param.h"
2
+
3
+@interface Dictionary : Param
4
+
5
+@end

+ 11
- 0
lib/ios/Dictionary.m View File

@@ -0,0 +1,11 @@
1
+#import "Dictionary.h"
2
+
3
+@interface Dictionary()
4
+
5
+@property (nonatomic, retain) NSDictionary* value;
6
+
7
+@end
8
+
9
+@implementation Dictionary
10
+
11
+@end

+ 8
- 0
lib/ios/DictionaryParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Dictionary.h"
3
+
4
+@interface DictionaryParser : NSObject
5
+
6
++ (Dictionary *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 10
- 0
lib/ios/DictionaryParser.m View File

@@ -0,0 +1,10 @@
1
+#import "DictionaryParser.h"
2
+#import "NullDictionary.h"
3
+
4
+@implementation DictionaryParser
5
+
6
++ (Dictionary *)parse:(NSDictionary *)json key:(NSString *)key {
7
+	return json[key] ? [[Dictionary alloc] initWithValue:json[key]] : [NullDictionary new];
8
+}
9
+
10
+@end

+ 9
- 0
lib/ios/Double.h View File

@@ -0,0 +1,9 @@
1
+#import "Param.h"
2
+
3
+@interface Double : Param
4
+
5
+- (double)get;
6
+
7
+- (double)getWithDefaultValue:(double)defaultValue;
8
+
9
+@end

+ 25
- 0
lib/ios/Double.m View File

@@ -0,0 +1,25 @@
1
+#import "Double.h"
2
+
3
+@interface Double()
4
+
5
+@property (nonatomic, retain) NSNumber* value;
6
+
7
+@end
8
+
9
+@implementation Double
10
+
11
+- (double)get {
12
+	return [[super get] doubleValue];
13
+}
14
+
15
+- (double)getWithDefaultValue:(double)defaultValue {
16
+	if (self.value) {
17
+		return [self.value doubleValue];
18
+	} else if (defaultValue) {
19
+		return defaultValue;
20
+	}
21
+	
22
+	return 0;
23
+}
24
+
25
+@end

+ 8
- 0
lib/ios/DoubleParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Double.h"
3
+
4
+@interface DoubleParser : NSObject
5
+
6
++ (Double *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 10
- 0
lib/ios/DoubleParser.m View File

@@ -0,0 +1,10 @@
1
+#import "DoubleParser.h"
2
+#import "NullDouble.h"
3
+
4
+@implementation DoubleParser
5
+
6
++ (Double *)parse:(NSDictionary *)json key:(NSString *)key {
7
+	return json[key] ? [[Double alloc] initWithValue:json[key]] : [NullDouble new];
8
+}
9
+
10
+@end

+ 10
- 0
lib/ios/Image.h View File

@@ -0,0 +1,10 @@
1
+#import "Param.h"
2
+#import <UIKit/UIKit.h>
3
+
4
+@interface Image : Param
5
+
6
+- (UIImage *)get;
7
+
8
+- (UIImage *)getWithDefaultValue:(UIImage *)defaultValue;
9
+
10
+@end

+ 19
- 0
lib/ios/Image.m View File

@@ -0,0 +1,19 @@
1
+#import "Image.h"
2
+
3
+@interface Image()
4
+
5
+@property (nonatomic, retain) UIImage* value;
6
+
7
+@end
8
+
9
+@implementation Image
10
+
11
+- (UIImage *)get {
12
+	return self.value;
13
+}
14
+
15
+- (UIImage *)getWithDefaultValue:(UIImage *)defaultValue {
16
+	return [super getWithDefaultValue:defaultValue];
17
+}
18
+
19
+@end

+ 8
- 0
lib/ios/ImageParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Image.h"
3
+
4
+@interface ImageParser : NSObject
5
+
6
++ (Image *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 11
- 0
lib/ios/ImageParser.m View File

@@ -0,0 +1,11 @@
1
+#import "ImageParser.h"
2
+#import "NullImage.h"
3
+#import <React/RCTConvert.h>
4
+
5
+@implementation ImageParser
6
+
7
++ (Image *)parse:(NSDictionary *)json key:(NSString *)key {
8
+	return json[key] ? [[Image alloc] initWithValue:[RCTConvert UIImage:json[key]]] : [NullImage new];
9
+}
10
+
11
+@end

+ 9
- 0
lib/ios/IntNumber.h View File

@@ -0,0 +1,9 @@
1
+#import "Param.h"
2
+
3
+@interface IntNumber : Param
4
+
5
+- (NSUInteger)get;
6
+
7
+- (NSUInteger)getWithDefaultValue:(NSUInteger)defaultValue;
8
+
9
+@end

+ 25
- 0
lib/ios/IntNumber.m View File

@@ -0,0 +1,25 @@
1
+#import "IntNumber.h"
2
+
3
+@interface IntNumber()
4
+
5
+@property (nonatomic, retain) NSNumber* value;
6
+
7
+@end
8
+
9
+@implementation IntNumber
10
+
11
+- (NSUInteger)get {
12
+	return [[super get] unsignedIntegerValue];
13
+}
14
+
15
+- (NSUInteger)getWithDefaultValue:(NSUInteger)defaultValue {
16
+	if (self.value) {
17
+		return [self.value unsignedIntegerValue];
18
+	} else if (defaultValue) {
19
+		return defaultValue;
20
+	}
21
+	
22
+	return 0;
23
+}
24
+
25
+@end

+ 8
- 0
lib/ios/IntNumberParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "IntNumber.h"
3
+
4
+@interface IntNumberParser : NSObject
5
+
6
++ (IntNumber *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 10
- 0
lib/ios/IntNumberParser.m View File

@@ -0,0 +1,10 @@
1
+#import "IntNumberParser.h"
2
+#import "NullIntNumber.h"
3
+
4
+@implementation IntNumberParser
5
+
6
++ (IntNumber *)parse:(NSDictionary *)json key:(NSString *)key {
7
+	return json[key] ? [[IntNumber alloc] initWithValue:json[key]] : [NullIntNumber new];
8
+}
9
+
10
+@end

+ 5
- 0
lib/ios/NullBool.h View File

@@ -0,0 +1,5 @@
1
+#import "Bool.h"
2
+
3
+@interface NullBool : Bool
4
+
5
+@end

+ 11
- 0
lib/ios/NullBool.m View File

@@ -0,0 +1,11 @@
1
+#import "NullBool.h"
2
+
3
+@implementation NullBool
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	
8
+	return self;
9
+}
10
+
11
+@end

+ 5
- 0
lib/ios/NullColor.h View File

@@ -0,0 +1,5 @@
1
+#import "Color.h"
2
+
3
+@interface NullColor : Color
4
+
5
+@end

+ 10
- 0
lib/ios/NullColor.m View File

@@ -0,0 +1,10 @@
1
+#import "NullColor.h"
2
+
3
+@implementation NullColor
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	return self;
8
+}
9
+
10
+@end

+ 5
- 0
lib/ios/NullDictionary.h View File

@@ -0,0 +1,5 @@
1
+#import "Dictionary.h"
2
+
3
+@interface NullDictionary : Dictionary
4
+
5
+@end

+ 10
- 0
lib/ios/NullDictionary.m View File

@@ -0,0 +1,10 @@
1
+#import "NullDictionary.h"
2
+
3
+@implementation NullDictionary
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	return self;
8
+}
9
+
10
+@end

+ 5
- 0
lib/ios/NullDouble.h View File

@@ -0,0 +1,5 @@
1
+#import "Double.h"
2
+
3
+@interface NullDouble : Double
4
+
5
+@end

+ 11
- 0
lib/ios/NullDouble.m View File

@@ -0,0 +1,11 @@
1
+#import "NullDouble.h"
2
+
3
+@implementation NullDouble
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	
8
+	return self;
9
+}
10
+
11
+@end

+ 5
- 0
lib/ios/NullImage.h View File

@@ -0,0 +1,5 @@
1
+#import "Image.h"
2
+
3
+@interface NullImage : Image
4
+
5
+@end

+ 11
- 0
lib/ios/NullImage.m View File

@@ -0,0 +1,11 @@
1
+#import "NullImage.h"
2
+
3
+@implementation NullImage
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	
8
+	return self;
9
+}
10
+
11
+@end

+ 5
- 0
lib/ios/NullIntNumber.h View File

@@ -0,0 +1,5 @@
1
+#import "IntNumber.h"
2
+
3
+@interface NullIntNumber : IntNumber
4
+
5
+@end

+ 12
- 0
lib/ios/NullIntNumber.m View File

@@ -0,0 +1,12 @@
1
+#import "NullIntNumber.h"
2
+
3
+@implementation NullIntNumber
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	
8
+	return self;
9
+}
10
+
11
+
12
+@end

+ 5
- 0
lib/ios/NullNumber.h View File

@@ -0,0 +1,5 @@
1
+#import "Number.h"
2
+
3
+@interface NullNumber : Number
4
+
5
+@end

+ 10
- 0
lib/ios/NullNumber.m View File

@@ -0,0 +1,10 @@
1
+#import "NullNumber.h"
2
+
3
+@implementation NullNumber
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	return self;
8
+}
9
+
10
+@end

+ 5
- 0
lib/ios/NullText.h View File

@@ -0,0 +1,5 @@
1
+#import "Text.h"
2
+
3
+@interface NullText : Text
4
+
5
+@end

+ 10
- 0
lib/ios/NullText.m View File

@@ -0,0 +1,10 @@
1
+#import "NullText.h"
2
+
3
+@implementation NullText
4
+
5
+- (instancetype)init {
6
+	self = [super initWithValue:nil];
7
+	return self;
8
+}
9
+
10
+@end

+ 11
- 0
lib/ios/Number.h View File

@@ -0,0 +1,11 @@
1
+#import <Foundation/Foundation.h>
2
+#import <UIKit/UIKit.h>
3
+#import "Param.h"
4
+
5
+@interface Number : Param
6
+
7
+- (NSNumber *)get;
8
+
9
+- (NSNumber *)getWithDefaultValue:(NSNumber *)defaultValue;
10
+
11
+@end

+ 19
- 0
lib/ios/Number.m View File

@@ -0,0 +1,19 @@
1
+#import "Number.h"
2
+
3
+@interface Number()
4
+
5
+@property (nonatomic, retain) NSNumber* value;
6
+
7
+@end
8
+
9
+@implementation Number
10
+
11
+- (NSNumber *)get {
12
+	return [super get];
13
+}
14
+
15
+- (NSNumber *)getWithDefaultValue:(NSNumber *)defaultValue {
16
+	return [super getWithDefaultValue:defaultValue];
17
+}
18
+
19
+@end

+ 8
- 0
lib/ios/NumberParser.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "Number.h"
3
+
4
+@interface NumberParser : NSObject
5
+
6
++ (Number *)parse:(NSDictionary *)json key:(NSString *)key;
7
+
8
+@end

+ 10
- 0
lib/ios/NumberParser.m View File

@@ -0,0 +1,10 @@
1
+#import "NumberParser.h"
2
+#import "NullNumber.h"
3
+
4
+@implementation NumberParser
5
+
6
++ (Number *)parse:(NSDictionary *)json key:(NSString *)key {
7
+	return json[key] ? [[Number alloc] initWithValue:json[key]] : [NullNumber new];
8
+}
9
+
10
+@end

+ 15
- 0
lib/ios/Param.h View File

@@ -0,0 +1,15 @@
1
+#import <Foundation/Foundation.h>
2
+
3
+@interface Param : NSObject
4
+
5
+- (instancetype)initWithValue:(id)value;
6
+
7
+- (id)get;
8
+
9
+- (id)getWithDefaultValue:(id)defaultValue;
10
+
11
+- (BOOL)hasValue;
12
+
13
+- (void)consume;
14
+
15
+@end

+ 46
- 0
lib/ios/Param.m View File

@@ -0,0 +1,46 @@
1
+#import "Param.h"
2
+
3
+@interface Param()
4
+
5
+@property (nonatomic, retain) id value;
6
+@property (nonatomic) BOOL consumed;
7
+
8
+@end
9
+
10
+@implementation Param
11
+
12
+- (instancetype)initWithValue:(id)value {
13
+	self = [super init];
14
+	
15
+	self.value = value;
16
+	
17
+	return self;
18
+}
19
+
20
+- (id)get {
21
+	if (!self.value) {
22
+		@throw [NSException exceptionWithName:@"Param get" reason:@"value does not exists" userInfo:nil];
23
+	}
24
+	
25
+	return self.value;
26
+}
27
+
28
+- (id)getWithDefaultValue:(id)defaultValue {
29
+	if (self.value) {
30
+		return self.value;
31
+	} else if (defaultValue) {
32
+		return defaultValue;
33
+	}
34
+	
35
+	return nil;
36
+}
37
+
38
+- (void)consume {
39
+	self.consumed = true;
40
+}
41
+
42
+- (BOOL)hasValue {
43
+	return self.value && !self.consumed;
44
+}
45
+
46
+@end

+ 8
- 1
lib/ios/RNNAnimationOptions.m View File

@@ -7,7 +7,14 @@
7 7
 @implementation RNNAnimationOptions
8 8
 
9 9
 - (instancetype)initWithDict:(NSDictionary *)dict {
10
-	return [super initWithDict:dict];
10
+	self = [super init];
11
+	
12
+	self.animations = dict[@"animations"];
13
+	self.duration = dict[@"duration"];
14
+	self.springDamping = dict[@"springDamping"];
15
+	self.springVelocity = dict[@"springVelocity"];
16
+	
17
+	return self;
11 18
 }
12 19
 
13 20
 - (NSNumber *)duration {

+ 6
- 6
lib/ios/RNNBackButtonOptions.h View File

@@ -2,11 +2,11 @@
2 2
 
3 3
 @interface RNNBackButtonOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSDictionary* icon;
6
-@property (nonatomic, strong) NSNumber* visible;
7
-@property (nonatomic, strong) NSString* title;
8
-@property (nonatomic, strong) NSString* transition;
9
-@property (nonatomic, strong) NSNumber* showTitle;
10
-@property (nonatomic, strong) NSNumber* color;
5
+@property (nonatomic, strong) Image* icon;
6
+@property (nonatomic, strong) Text* title;
7
+@property (nonatomic, strong) Text* transition;
8
+@property (nonatomic, strong) Color* color;
9
+@property (nonatomic, strong) Bool* showTitle;
10
+@property (nonatomic, strong) Bool* visible;
11 11
 
12 12
 @end

+ 10
- 44
lib/ios/RNNBackButtonOptions.m View File

@@ -1,52 +1,18 @@
1 1
 #import "RNNBackButtonOptions.h"
2
-#import "UIImage+tint.h"
3 2
 
4 3
 @implementation RNNBackButtonOptions
5 4
 
6
-- (void)applyOn:(UIViewController *)viewController {
7
-	if (self.visible) {
8
-		viewController.navigationItem.hidesBackButton = ![self.visible boolValue];
9
-	}
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
10 7
 	
11
-	[self applyOnNavigationController:viewController.navigationController];
12
-}
13
-
14
-- (void)applyOnNavigationController:(UINavigationController *)navigationController {
15
-  UIBarButtonItem *backItem = [[UIBarButtonItem alloc] init];
16
-  	UIImage* tintedIcon = self.tintedIconIfAvailable;
17
-	if (tintedIcon) {
18
-		backItem.image = tintedIcon;
19
-		[navigationController.navigationBar setBackIndicatorImage:[UIImage new]];	
20
-		[navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage new]];
21
-	}
22
-  
23
-	if (self.color) {
24
-	  	backItem.tintColor = [RCTConvert UIColor:self.color];
25
-	}
26
-  
27
-	if (self.showTitle && ![self.showTitle boolValue]) {
28
-	  	self.title = @"";
29
-	}
30
-  
31
-  	[self setBackItem:backItem onNavigationController:navigationController];
32
-}
33
-
34
-- (void)setBackItem:(UIBarButtonItem *)backItem onNavigationController:(UINavigationController *)navigationController {
35
-	NSArray *viewControllers = navigationController.viewControllers;
36
-	UIViewController *lastViewControllerInStack = [viewControllers lastObject];
37
-	backItem.title = self.title ? self.title : lastViewControllerInStack.navigationItem.title;
38
-	lastViewControllerInStack.navigationItem.backBarButtonItem = backItem;
39
-}
40
-
41
-- (UIImage *)tintedIconIfAvailable {
42
-	if (self.icon) {
43
-		UIImage *image = [RCTConvert UIImage:self.icon];
44
-	  	return self.color
45
-	  		? [[image withTintColor:[RCTConvert UIColor:self.color]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
46
-	  		: image;
47
-	}
48
-  
49
-  	return nil;
8
+	self.icon = [ImageParser parse:dict key:@"icon"];
9
+	self.title = [TextParser parse:dict key:@"title"];
10
+	self.transition = [TextParser parse:dict key:@"transition"];
11
+	self.color = [ColorParser parse:dict key:@"color"];
12
+	self.showTitle = [BoolParser parse:dict key:@"showTitle"];
13
+	self.visible = [BoolParser parse:dict key:@"visible"];
14
+	
15
+	return self;
50 16
 }
51 17
 
52 18
 @end

+ 4
- 4
lib/ios/RNNBackgroundOptions.h View File

@@ -3,10 +3,10 @@
3 3
 
4 4
 @interface RNNBackgroundOptions : RNNOptions
5 5
 
6
-@property (nonatomic, strong) NSNumber* color;
7
-@property (nonatomic, strong) NSNumber* translucent;
8
-@property (nonatomic, strong) NSNumber* blur;
6
+@property (nonatomic, strong) Color* color;
7
+@property (nonatomic, strong) Bool* translucent;
8
+@property (nonatomic, strong) Bool* blur;
9
+@property (nonatomic, strong) Bool* clipToBounds;
9 10
 @property (nonatomic, strong) RNNComponentOptions* component;
10
-@property (nonatomic, strong) NSNumber* clipToBounds; 
11 11
 
12 12
 @end

+ 8
- 90
lib/ios/RNNBackgroundOptions.m View File

@@ -1,100 +1,18 @@
1 1
 #import "RNNBackgroundOptions.h"
2 2
 
3
-extern const NSInteger BLUR_TOPBAR_TAG;
4
-const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
5
-
6
-@interface RNNBackgroundOptions()
7
-
8
-@property (nonatomic, strong) NSMutableDictionary* originalTopBarImages;
9
-
10
-@end
11 3
 
12 4
 @implementation RNNBackgroundOptions
13 5
 
14
-- (void)applyOnNavigationController:(UINavigationController *)navigationController {
15
-	if (self.translucent) {
16
-		navigationController.navigationBar.translucent = [self.translucent boolValue];
17
-	} else {
18
-		navigationController.navigationBar.translucent = NO;
19
-	}
6
+- (instancetype)initWithDict:(NSDictionary *)dict {
7
+	self = [super init];
20 8
 	
21
-	if ([self.blur boolValue]) {
22
-		if (![navigationController.navigationBar viewWithTag:BLUR_TOPBAR_TAG]) {
23
-
24
-			[navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
25
-			navigationController.navigationBar.shadowImage = [UIImage new];
26
-			UIVisualEffectView *blur = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
27
-			CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
28
-			blur.frame = CGRectMake(0, -1 * statusBarFrame.size.height, navigationController.navigationBar.frame.size.width, navigationController.navigationBar.frame.size.height + statusBarFrame.size.height);
29
-			blur.userInteractionEnabled = NO;
30
-			blur.tag = BLUR_TOPBAR_TAG;
31
-			[navigationController.navigationBar insertSubview:blur atIndex:0];
32
-			[navigationController.navigationBar sendSubviewToBack:blur];
33
-		}
34
-	} else {
35
-		UIView *blur = [navigationController.navigationBar viewWithTag:BLUR_TOPBAR_TAG];
36
-		if (blur) {
37
-			[navigationController.navigationBar setBackgroundImage: nil forBarMetrics:UIBarMetricsDefault];
38
-			navigationController.navigationBar.shadowImage = nil;
39
-			[blur removeFromSuperview];
40
-		}
41
-	}
9
+	self.color = [ColorParser parse:dict key:@"color"];
10
+	self.translucent = [BoolParser parse:dict key:@"translucent"];
11
+	self.blur = [BoolParser parse:dict key:@"blur"];
12
+	self.clipToBounds = [BoolParser parse:dict key:@"clipToBounds"];
13
+	self.component = [[RNNComponentOptions alloc] initWithDict:dict[@"component"]];
42 14
 	
43
-	if (self.color && ![self.color isKindOfClass:[NSNull class]]) {
44
-		UIColor* backgroundColor = [RCTConvert UIColor:self.color];
45
-
46
-		CGFloat bgColorAlpha = CGColorGetAlpha(backgroundColor.CGColor);
47
-
48
-		if (bgColorAlpha == 0.0) {
49
-			if (![navigationController.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG]){
50
-				[self storeOriginalTopBarImages:navigationController];
51
-				UIView *transparentView = [[UIView alloc] initWithFrame:CGRectZero];
52
-				transparentView.backgroundColor = [UIColor clearColor];
53
-				transparentView.tag = TOP_BAR_TRANSPARENT_TAG;
54
-				[navigationController.navigationBar insertSubview:transparentView atIndex:0];
55
-			}
56
-			navigationController.navigationBar.translucent = YES;
57
-			[navigationController.navigationBar setBackgroundColor:[UIColor clearColor]];
58
-			navigationController.navigationBar.shadowImage = [UIImage new];
59
-			[navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
60
-		} else {
61
-			navigationController.navigationBar.barTintColor = backgroundColor;
62
-			UIView *transparentView = [navigationController.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG];
63
-			if (transparentView){
64
-				[transparentView removeFromSuperview];
65
-				[navigationController.navigationBar setBackgroundImage:self.originalTopBarImages[@"backgroundImage"] forBarMetrics:UIBarMetricsDefault];
66
-				navigationController.navigationBar.shadowImage = self.originalTopBarImages[@"shadowImage"];
67
-				self.originalTopBarImages = nil;
68
-			}
69
-		}
70
-	} else {
71
-		UIView *transparentView = [navigationController.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG];
72
-		if (transparentView){
73
-			[transparentView removeFromSuperview];
74
-			[navigationController.navigationBar setBackgroundImage:self.originalTopBarImages[@"backgroundImage"] forBarMetrics:UIBarMetricsDefault];
75
-			navigationController.navigationBar.shadowImage = self.originalTopBarImages[@"shadowImage"];
76
-			self.originalTopBarImages = nil;
77
-		}
78
-	}
79
-
80
-	if (self.clipToBounds) {
81
-		navigationController.navigationBar.clipsToBounds = [self.clipToBounds boolValue];
82
-	} else {
83
-		navigationController.navigationBar.clipsToBounds = NO;
84
-	}
85
-}
86
-
87
-- (void)storeOriginalTopBarImages:(UINavigationController *)navigationController {
88
-	NSMutableDictionary *originalTopBarImages = [@{} mutableCopy];
89
-	UIImage *bgImage = [navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
90
-	if (bgImage != nil) {
91
-		originalTopBarImages[@"backgroundImage"] = bgImage;
92
-	}
93
-	UIImage *shadowImage = navigationController.navigationBar.shadowImage;
94
-	if (shadowImage != nil) {
95
-		originalTopBarImages[@"shadowImage"] = shadowImage;
96
-	}
97
-	self.originalTopBarImages = originalTopBarImages;
15
+	return self;
98 16
 }
99 17
 
100 18
 @end

+ 13
- 3
lib/ios/RNNBasePresenter.h View File

@@ -1,9 +1,19 @@
1
-#import <Foundation/Foundation.h>
2 1
 #import "RNNNavigationOptions.h"
3 2
 
4 3
 @interface RNNBasePresenter : NSObject
5 4
 
6
-- (void)present:(RNNNavigationOptions *)options onViewControllerDidLoad:(UIViewController *)viewController;
7
-- (void)present:(RNNNavigationOptions *)options onViewControllerWillAppear:(UIViewController *)viewController;
5
+@property (nonatomic, weak) id bindedViewController;
6
+
7
+@property (nonatomic, retain) RNNNavigationOptions* defaultOptions;
8
+
9
+- (void)bindViewController:(UIViewController *)bindedViewController;
10
+
11
+- (void)applyOptions:(RNNNavigationOptions *)initialOptions;
12
+
13
+- (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options;
14
+
15
+- (void)mergeOptions:(RNNNavigationOptions *)options;
16
+
17
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
8 18
 
9 19
 @end

+ 31
- 4
lib/ios/RNNBasePresenter.m View File

@@ -1,13 +1,40 @@
1 1
 #import "RNNBasePresenter.h"
2
+#import "RNNBottomTabPresenter.h"
3
+
4
+@interface RNNBasePresenter()
5
+
6
+@property (nonatomic, strong) RNNBottomTabPresenter* bottomTabPresenter;
7
+
8
+@end
2 9
 
3 10
 @implementation RNNBasePresenter
4 11
 
5
-- (void)present:(RNNNavigationOptions *)options onViewControllerWillAppear:(UIViewController *)viewController {
6
-	[options applyOn:viewController];
12
+- (instancetype)init {
13
+	self = [super init];
14
+	self.bottomTabPresenter = [[RNNBottomTabPresenter alloc] init];
15
+	return self;
16
+}
17
+
18
+- (void)bindViewController:(UIViewController *)bindedViewController {
19
+	_bindedViewController = bindedViewController;
20
+	[self.bottomTabPresenter bindViewController:bindedViewController];
21
+}
22
+
23
+- (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options {
24
+	[self.bottomTabPresenter applyOptions:options];
25
+}
26
+
27
+- (void)applyOptions:(RNNNavigationOptions *)initialOptions {
28
+	[self.bottomTabPresenter applyOptions:initialOptions];
29
+}
30
+
31
+- (void)mergeOptions:(RNNNavigationOptions *)options {
32
+	
7 33
 }
8 34
 
9
-- (void)present:(RNNNavigationOptions *)options onViewControllerDidLoad:(UIViewController *)viewController {
10
-	[options applyOn:viewController];
35
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions {
36
+	_defaultOptions = defaultOptions;
37
+	[self.bottomTabPresenter setDefaultOptions:defaultOptions];
11 38
 }
12 39
 
13 40
 @end

+ 14
- 14
lib/ios/RNNBottomTabOptions.h View File

@@ -3,20 +3,20 @@
3 3
 @interface RNNBottomTabOptions : RNNOptions
4 4
 
5 5
 @property (nonatomic) NSUInteger tag;
6
-@property (nonatomic, strong) NSString* text;
7
-@property (nonatomic, strong) NSString* badge;
8
-@property (nonatomic, strong) NSDictionary* badgeColor;
9
-@property (nonatomic, strong) NSString* testID;
10
-@property (nonatomic, strong) NSNumber* visible;
11
-@property (nonatomic, strong) NSDictionary* icon;
12
-@property (nonatomic, strong) NSDictionary* selectedIcon;
13
-@property (nonatomic, strong) NSDictionary* iconColor;
14
-@property (nonatomic, strong) NSDictionary* selectedIconColor;
15
-@property (nonatomic, strong) NSDictionary* textColor;
16
-@property (nonatomic, strong) NSDictionary* selectedTextColor;
17
-@property (nonatomic, strong) NSString* fontFamily;
18
-@property (nonatomic, strong) NSNumber* fontSize;
6
+@property (nonatomic, strong) Text* text;
7
+@property (nonatomic, strong) Text* badge;
8
+@property (nonatomic, strong) Text* fontFamily;
9
+@property (nonatomic, strong) Text* testID;
10
+@property (nonatomic, strong) Color* badgeColor;
11
+@property (nonatomic, strong) Image* icon;
12
+@property (nonatomic, strong) Image* selectedIcon;
13
+@property (nonatomic, strong) Color* iconColor;
14
+@property (nonatomic, strong) Color* selectedIconColor;
15
+@property (nonatomic, strong) Color* selectedTextColor;
16
+@property (nonatomic, strong) Dictionary* iconInsets;
17
+@property (nonatomic, strong) Color* textColor;
18
+@property (nonatomic, strong) Number* fontSize;
19
+@property (nonatomic, strong) Bool* visible;
19 20
 
20
-@property (nonatomic, strong) NSDictionary* iconInsets;
21 21
 
22 22
 @end

+ 19
- 136
lib/ios/RNNBottomTabOptions.m View File

@@ -1,150 +1,33 @@
1 1
 #import "RNNBottomTabOptions.h"
2 2
 #import "UIImage+tint.h"
3
+#import "UITabBarController+RNNOptions.h"
4
+#import "UIViewController+RNNOptions.h"
5
+#import "RNNTabBarItemCreator.h"
3 6
 
4 7
 @implementation RNNBottomTabOptions
5 8
 
6
--(instancetype)initWithDict:(NSDictionary *)tabItemDict {
9
+- (instancetype)initWithDict:(NSDictionary *)dict {
7 10
 	self = [super init];
8 11
 	
9
-	[self mergeWith:tabItemDict];
10
-	self.tag = [tabItemDict[@"tag"] integerValue];
12
+	self.text = [TextParser parse:dict key:@"text"];
13
+	self.badge = [TextParser parse:dict key:@"badge"];
14
+	self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
15
+	self.testID = [TextParser parse:dict key:@"testID"];
11 16
 	
12
-	return self;
13
-}
14
-
15
-- (void)applyOn:(UIViewController *)viewController {
16
-	UIViewController* topViewController = [self getTabControllerFirstChild:viewController];
17
-	if (self.text || self.icon || self.selectedIcon) {
18
-		UITabBarItem* tabItem = topViewController.tabBarItem;
19
-		
20
-		tabItem.selectedImage = [self getSelectedIconImage];
21
-		tabItem.image = [self getIconImage];
22
-		tabItem.title = self.text;
23
-		tabItem.tag = self.tag;
24
-		tabItem.accessibilityIdentifier = self.testID;
25
-		
26
-		if (self.iconInsets && ![self.iconInsets isKindOfClass:[NSNull class]]) {
27
-			id topInset = self.iconInsets[@"top"];
28
-			id leftInset = self.iconInsets[@"left"];
29
-			id bottomInset = self.iconInsets[@"bottom"];
30
-			id rightInset = self.iconInsets[@"right"];
31
-			
32
-			CGFloat top = topInset != (id)[NSNull null] ? [RCTConvert CGFloat:topInset] : 0;
33
-			CGFloat left = topInset != (id)[NSNull null] ? [RCTConvert CGFloat:leftInset] : 0;
34
-			CGFloat bottom = topInset != (id)[NSNull null] ? [RCTConvert CGFloat:bottomInset] : 0;
35
-			CGFloat right = topInset != (id)[NSNull null] ? [RCTConvert CGFloat:rightInset] : 0;
36
-			
37
-			tabItem.imageInsets = UIEdgeInsetsMake(top, left, bottom, right);
38
-		}
39
-		
40
-		[self appendTitleAttributes:tabItem];
41
-		
42
-		[topViewController setTabBarItem:tabItem];
43
-	}
44
-	
45
-	if (self.badge) {
46
-		NSString *badge = nil;
47
-		if (self.badge != nil && ![self.badge isEqual:[NSNull null]]) {
48
-			badge = [RCTConvert NSString:self.badge];
49
-		}
50
-		UITabBarItem *tabBarItem = topViewController.tabBarItem;
51
-		tabBarItem.badgeValue = badge;
52
-		if (self.badgeColor) {
53
-			tabBarItem.badgeColor = [RCTConvert UIColor:self.badgeColor];
54
-		}
55
-		
56
-		if ([self.badge isEqual:[NSNull null]] || [self.badge isEqualToString:@""]) {
57
-			tabBarItem.badgeValue = nil;
58
-		}
59
-	}
60
-	
61
-	if (self.visible) {
62
-		[topViewController.tabBarController setSelectedIndex:[viewController.tabBarController.viewControllers indexOfObject:viewController]];
63
-	}
64
-	
65
-	[self resetOptions];
66
-}
67
-
68
-- (UIImage *)getIconImage {
69
-	return [self getIconImageWithTint:self.iconColor];
70
-}
71
-
72
-- (UIImage *)getSelectedIconImage {
73
-	if (self.selectedIcon) {
74
-		if (self.selectedIconColor) {
75
-			return [[[RCTConvert UIImage:self.selectedIcon] withTintColor:[RCTConvert UIColor:self.selectedIconColor]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
76
-		} else {
77
-			return [[RCTConvert UIImage:self.selectedIcon] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
78
-		}
79
-	} else {
80
-		return [self getIconImageWithTint:self.selectedIconColor];
81
-	}
82
-	
83
-	return nil;
84
-}
85
-
86
-- (UIImage *)getIconImageWithTint:(NSDictionary *)tintColor {
87
-	if (self.icon) {
88
-		if (tintColor) {
89
-			return [[[RCTConvert UIImage:self.icon] withTintColor:[RCTConvert UIColor:tintColor]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
90
-		} else {
91
-			return [[RCTConvert UIImage:self.icon] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
92
-		}
93
-	}
94
-	
95
-	return nil;
96
-}
97
-
98
-- (void)appendTitleAttributes:(UITabBarItem *)tabItem {
99
-	NSMutableDictionary* selectedAttributes = [NSMutableDictionary dictionaryWithDictionary:[tabItem titleTextAttributesForState:UIControlStateNormal]];
100
-	if (self.selectedTextColor) {
101
-		selectedAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:self.selectedTextColor];
102
-	} else {
103
-		selectedAttributes[NSForegroundColorAttributeName] = [UIColor blackColor];
104
-	}
105
-	
106
-	selectedAttributes[NSFontAttributeName] = [self tabBarTextFont];
107
-	[tabItem setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];
108 17
 	
18
+	self.badgeColor = [ColorParser parse:dict key:@"badgeColor"];
19
+	self.icon = [ImageParser parse:dict key:@"icon"];
20
+	self.selectedIcon = [ImageParser parse:dict key:@"selectedIcon"];
21
+	self.iconColor = [ColorParser parse:dict key:@"iconColor"];
22
+	self.selectedIconColor = [ColorParser parse:dict key:@"selectedIconColor"];
23
+	self.selectedTextColor = [ColorParser parse:dict key:@"selectedTextColor"];
24
+	self.iconInsets = [DictionaryParser parse:dict key:@"iconInsets"];
109 25
 	
110
-	NSMutableDictionary* normalAttributes = [NSMutableDictionary dictionaryWithDictionary:[tabItem titleTextAttributesForState:UIControlStateNormal]];
111
-	if (self.textColor) {
112
-		normalAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:self.textColor];
113
-	} else {
114
-		normalAttributes[NSForegroundColorAttributeName] = [UIColor blackColor];
115
-	}
26
+	self.textColor = [ColorParser parse:dict key:@"textColor"];
27
+	self.fontSize = [NumberParser parse:dict key:@"fontSize"];
28
+	self.visible = [BoolParser parse:dict key:@"visible"];
116 29
 	
117
-	normalAttributes[NSFontAttributeName] = [self tabBarTextFont];
118
-	[tabItem setTitleTextAttributes:normalAttributes forState:UIControlStateNormal];
119
-}
120
-
121
-
122
--(UIFont *)tabBarTextFont {
123
-	if (self.fontFamily) {
124
-		return [UIFont fontWithName:self.fontFamily size:self.tabBarTextFontSizeValue];
125
-	}
126
-	else if (self.fontSize) {
127
-		return [UIFont systemFontOfSize:self.tabBarTextFontSizeValue];
128
-	}
129
-	else {
130
-		return nil;
131
-	}
132
-}
133
-
134
--(CGFloat)tabBarTextFontSizeValue {
135
-	return self.fontSize ? [self.fontSize floatValue] : 10;
136
-}
137
-
138
-- (UIViewController *)getTabControllerFirstChild:(UIViewController *)viewController {
139
-	while (viewController != nil) {
140
-		if ([viewController.parentViewController isKindOfClass:[UITabBarController class]] || !viewController.parentViewController) {
141
-			return viewController;
142
-		}
143
-		
144
-		viewController = viewController.parentViewController;
145
-	}
146
-	
147
-	return nil;
30
+	return self;
148 31
 }
149 32
 
150 33
 -(void)resetOptions {

+ 11
- 0
lib/ios/RNNBottomTabPresenter.h View File

@@ -0,0 +1,11 @@
1
+#import "RNNBasePresenter.h"
2
+
3
+@interface RNNBottomTabPresenter : NSObject
4
+
5
+- (void)bindViewController:(UIViewController *)viewController;
6
+
7
+- (void)applyOptions:(RNNNavigationOptions *)options;
8
+
9
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
10
+
11
+@end

+ 33
- 0
lib/ios/RNNBottomTabPresenter.m View File

@@ -0,0 +1,33 @@
1
+#import "RNNBottomTabPresenter.h"
2
+#import "RNNTabBarItemCreator.h"
3
+
4
+@interface RNNBottomTabPresenter()
5
+
6
+@property (nonatomic, weak) id bindedViewController;
7
+@property (nonatomic, retain) RNNNavigationOptions* defaultOptions;
8
+
9
+@end
10
+
11
+@implementation RNNBottomTabPresenter
12
+
13
+- (void)bindViewController:(UIViewController *)viewController {
14
+	_bindedViewController = viewController;
15
+}
16
+
17
+- (void)applyOptions:(RNNNavigationOptions *)options {
18
+	UIViewController* viewController = self.bindedViewController;
19
+	if ((options.bottomTab.text.hasValue || options.bottomTab.icon.hasValue || options.bottomTab.selectedIcon.hasValue)) {
20
+		RNNNavigationOptions* withDefault = (RNNNavigationOptions *)[[options copy] withDefault:self.defaultOptions];
21
+		UITabBarItem* tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
22
+		viewController.tabBarItem = tabItem;
23
+		[options.bottomTab.text consume];
24
+		[options.bottomTab.icon consume];
25
+		[options.bottomTab.selectedIcon consume];
26
+	}
27
+}
28
+
29
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions {
30
+	_defaultOptions = defaultOptions;
31
+}
32
+
33
+@end

+ 13
- 13
lib/ios/RNNBottomTabsOptions.h View File

@@ -2,19 +2,19 @@
2 2
 
3 3
 @interface RNNBottomTabsOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSNumber* visible;
6
-@property (nonatomic, strong) NSNumber* currentTabIndex;
7
-@property (nonatomic, strong) NSString* testID;
8
-@property (nonatomic, strong) NSNumber* drawBehind;
9
-@property (nonatomic, strong) NSString* currentTabId;
5
+@property (nonatomic, strong) Bool* visible;
6
+@property (nonatomic, strong) IntNumber* currentTabIndex;
7
+@property (nonatomic, strong) Bool* drawBehind;
8
+@property (nonatomic, strong) Color* tabColor;
9
+@property (nonatomic, strong) Color* selectedTabColor;
10
+@property (nonatomic, strong) Bool* translucent;
11
+@property (nonatomic, strong) Bool* hideShadow;
12
+@property (nonatomic, strong) Color* backgroundColor;
13
+@property (nonatomic, strong) Number* fontSize;
10 14
 
11
-@property (nonatomic, strong) NSNumber* tabColor;
12
-@property (nonatomic, strong) NSNumber* selectedTabColor;
13
-@property (nonatomic, strong) NSString* barStyle;
14
-@property (nonatomic, strong) NSNumber* translucent;
15
-@property (nonatomic, strong) NSNumber* hideShadow;
16
-@property (nonatomic, strong) NSNumber* backgroundColor;
17
-@property (nonatomic, strong) NSString* fontFamily;
18
-@property (nonatomic, strong) NSNumber* fontSize;
15
+@property (nonatomic, strong) Text* testID;
16
+@property (nonatomic, strong) Text* currentTabId;
17
+@property (nonatomic, strong) Text* barStyle;
18
+@property (nonatomic, strong) Text* fontFamily;
19 19
 
20 20
 @end

+ 16
- 66
lib/ios/RNNBottomTabsOptions.m View File

@@ -1,76 +1,26 @@
1 1
 #import "RNNBottomTabsOptions.h"
2
-#import "RNNTabBarController.h"
3
-extern const NSInteger BLUR_TOPBAR_TAG;
4 2
 
5 3
 @implementation RNNBottomTabsOptions
6 4
 
7
-- (void)applyOn:(UIViewController *)viewController {
8
-	if (self.currentTabIndex) {
9
-		[viewController.tabBarController setSelectedIndex:[self.currentTabIndex unsignedIntegerValue]];
10
-	}
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
11 7
 	
12
-	if (self.currentTabId) {
13
-		[(RNNTabBarController*)viewController.tabBarController setSelectedIndexByComponentID:self.currentTabId];
14
-	}
8
+	self.visible = [BoolParser parse:dict key:@"visible"];
9
+	self.currentTabIndex = [IntNumberParser parse:dict key:@"currentTabIndex"];
10
+	self.drawBehind = [BoolParser parse:dict key:@"drawBehind"];
11
+	self.tabColor = [ColorParser parse:dict key:@"tabColor"];
12
+	self.selectedTabColor = [ColorParser parse:dict key:@"selectedTabColor"];
13
+	self.translucent = [BoolParser parse:dict key:@"translucent"];
14
+	self.hideShadow = [BoolParser parse:dict key:@"hideShadow"];
15
+	self.backgroundColor = [ColorParser parse:dict key:@"backgroundColor"];
16
+	self.fontSize = [NumberParser parse:dict key:@"fontSize"];
15 17
 	
16
-	if (self.testID) {
17
-		viewController.tabBarController.tabBar.accessibilityIdentifier = self.testID;
18
-	}
18
+	self.testID = [TextParser parse:dict key:@"testID"];
19
+	self.currentTabId = [TextParser parse:dict key:@"currentTabId"];
20
+	self.barStyle = [TextParser parse:dict key:@"barStyle"];
21
+	self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
19 22
 	
20
-	if (self.drawBehind) {
21
-		if ([self.drawBehind boolValue]) {
22
-			[viewController setExtendedLayoutIncludesOpaqueBars:YES];
23
-			viewController.edgesForExtendedLayout |= UIRectEdgeBottom;
24
-		} else {
25
-			[viewController setExtendedLayoutIncludesOpaqueBars:NO];
26
-			viewController.edgesForExtendedLayout &= ~UIRectEdgeBottom;
27
-		}
28
-	}
29
-	
30
-	if (self.backgroundColor) {
31
-		viewController.tabBarController.tabBar.barTintColor = [RCTConvert UIColor:self.backgroundColor];
32
-	} else {
33
-		viewController.tabBarController.tabBar.barTintColor = nil;
34
-	}
35
-	
36
-	if (self.barStyle) {
37
-		viewController.tabBarController.tabBar.barStyle = [RCTConvert UIBarStyle:self.barStyle];
38
-	} else {
39
-		viewController.tabBarController.tabBar.barStyle = UIBarStyleDefault;
40
-	}
41
-
42
-	if (self.translucent) {
43
-		viewController.tabBarController.tabBar.translucent = [self.translucent boolValue];
44
-	} else {
45
-		viewController.tabBarController.tabBar.translucent = NO;
46
-	}
47
-	
48
-	if (self.hideShadow) {
49
-		viewController.tabBarController.tabBar.clipsToBounds = [self.hideShadow boolValue];
50
-	}
51
-
52
-	[self resetOptions];
53
-}
54
-
55
--(UIFont *)tabBarTextFont {
56
-	if (self.fontFamily) {
57
-		return [UIFont fontWithName:self.fontFamily size:self.tabBarTextFontSizeValue];
58
-	}
59
-	else if (self.fontSize) {
60
-		return [UIFont systemFontOfSize:self.tabBarTextFontSizeValue];
61
-	}
62
-	else {
63
-		return nil;
64
-	}
65
-}
66
-
67
--(CGFloat)tabBarTextFontSizeValue {
68
-	return self.fontSize ? [self.fontSize floatValue] : 10;
69
-}
70
-
71
-- (void)resetOptions {
72
-	self.currentTabId = nil;
73
-	self.currentTabIndex = nil;
23
+	return self;
74 24
 }
75 25
 
76 26
 @end

+ 7
- 7
lib/ios/RNNButtonOptions.h View File

@@ -2,12 +2,12 @@
2 2
 
3 3
 @interface RNNButtonOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSString* fontFamily;
6
-@property (nonatomic, strong) NSNumber* fontSize;
7
-@property (nonatomic, strong) NSNumber* color;
8
-@property (nonatomic, strong) NSNumber* disabledColor;
9
-@property (nonatomic, strong) NSNumber* icon;
10
-@property (nonatomic, strong) NSString* text;
11
-@property (nonatomic, strong) NSNumber* enabled;
5
+@property (nonatomic, strong) Text* fontFamily;
6
+@property (nonatomic, strong) Text* text;
7
+@property (nonatomic, strong) Number* fontSize;
8
+@property (nonatomic, strong) Color* color;
9
+@property (nonatomic, strong) Color* disabledColor;
10
+@property (nonatomic, strong) Image* icon;
11
+@property (nonatomic, strong) Bool* enabled;
12 12
 
13 13
 @end

+ 15
- 0
lib/ios/RNNButtonOptions.m View File

@@ -2,4 +2,19 @@
2 2
 
3 3
 @implementation RNNButtonOptions
4 4
 
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
7
+	
8
+	self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
9
+	self.text = [TextParser parse:dict key:@"text"];
10
+	self.fontSize = [NumberParser parse:dict key:@"fontSize"];
11
+	self.color = [ColorParser parse:dict key:@"color"];
12
+	self.disabledColor = [ColorParser parse:dict key:@"disabledColor"];
13
+	self.icon = [ImageParser parse:dict key:@"icon"];
14
+	self.enabled = [BoolParser parse:dict key:@"enabled"];
15
+	
16
+
17
+	return self;
18
+}
19
+
5 20
 @end

+ 27
- 15
lib/ios/RNNCommandsHandler.m View File

@@ -8,6 +8,7 @@
8 8
 #import "RNNElementFinder.h"
9 9
 #import "React/RCTUIManager.h"
10 10
 #import "RNNErrorHandler.h"
11
+#import "RNNDefaultOptionsHelper.h"
11 12
 
12 13
 static NSString* const setRoot	= @"setRoot";
13 14
 static NSString* const setStackRoot	= @"setStackRoot";
@@ -68,20 +69,27 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
68 69
 	[self assertReady];
69 70
 	
70 71
 	UIViewController<RNNLayoutProtocol>* vc = (UIViewController<RNNLayoutProtocol>*)[_store findComponentForId:componentId];
71
-	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
72
+	RNNNavigationOptions* newOptions = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
72 73
 	if ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] || [vc isKindOfClass:[RNNRootViewController class]]) {
73 74
 		[CATransaction begin];
74 75
 		[CATransaction setCompletionBlock:completion];
75 76
 		
76
-		[vc.getLeafViewController mergeAndPresentOptions:options];
77
-		
77
+		[vc.options overrideOptions:newOptions];
78
+		[vc mergeOptions:newOptions];
79
+
78 80
 		[CATransaction commit];
79 81
 	}
80 82
 }
81 83
 
82 84
 - (void)setDefaultOptions:(NSDictionary*)optionsDict completion:(RNNTransitionCompletionBlock)completion {
83 85
 	[self assertReady];
84
-	[_controllerFactory.optionsManager setDefaultOptionsDict:optionsDict];
86
+	RNNNavigationOptions* defaultOptions = [[RNNNavigationOptions alloc] initWithDict:optionsDict];
87
+	[_controllerFactory setDefaultOptions:defaultOptions];
88
+	
89
+	UIViewController *rootViewController = UIApplication.sharedApplication.delegate.window.rootViewController;
90
+	[RNNDefaultOptionsHelper recrusivelySetDefaultOptions:defaultOptions onRootViewController:rootViewController];
91
+	
92
+	completion();
85 93
 }
86 94
 
87 95
 - (void)push:(NSString*)componentId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
@@ -145,7 +153,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
145 153
 	[self assertReady];
146 154
 	
147 155
 	UIViewController<RNNParentProtocol> *newVC = [_controllerFactory createLayoutAndSaveToStore:layout];
148
-	RNNNavigationOptions* options = [newVC getLeafViewController].options;
156
+	RNNNavigationOptions* options = [newVC getCurrentChild].options;
149 157
 	UIViewController *fromVC = [_store findComponentForId:componentId];
150 158
 	__weak typeof(RNNEventEmitter*) weakEventEmitter = _eventEmitter;
151 159
 	[_stackManager setStackRoot:newVC fromViewController:fromVC animated:options.animations.setStackRoot.enable completion:^{
@@ -154,11 +162,12 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
154 162
 	} rejection:rejection];
155 163
 }
156 164
 
157
-- (void)pop:(NSString*)componentId mergeOptions:(NSDictionary*)options completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
165
+- (void)pop:(NSString*)componentId mergeOptions:(NSDictionary*)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
158 166
 	[self assertReady];
159 167
 	
160 168
 	RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
161
-	[vc.options mergeWith:options];
169
+	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
170
+	[vc.options overrideOptions:options];
162 171
 	
163 172
 	UINavigationController *nvc = vc.navigationController;
164 173
 	
@@ -183,10 +192,11 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
183 192
 	}];
184 193
 }
185 194
 
186
-- (void)popTo:(NSString*)componentId mergeOptions:(NSDictionary *)options completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
195
+- (void)popTo:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
187 196
 	[self assertReady];
188 197
 	RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
189
-	[vc.options mergeWith:options];
198
+	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
199
+	[vc.options overrideOptions:options];
190 200
 	
191 201
 	[_stackManager popTo:vc animated:vc.options.animations.pop.enable completion:^(NSArray *poppedViewControllers) {
192 202
 		[_eventEmitter sendOnNavigationCommandCompletion:popTo params:@{@"componentId": componentId}];
@@ -195,10 +205,11 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
195 205
 	} rejection:rejection];
196 206
 }
197 207
 
198
-- (void)popToRoot:(NSString*)componentId mergeOptions:(NSDictionary *)options completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
208
+- (void)popToRoot:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
199 209
 	[self assertReady];
200 210
 	RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
201
-	[vc.options mergeWith:options];
211
+	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
212
+	[vc.options overrideOptions:options];
202 213
 	
203 214
 	[CATransaction begin];
204 215
 	[CATransaction setCompletionBlock:^{
@@ -220,15 +231,15 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
220 231
 	
221 232
 	UIViewController<RNNParentProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
222 233
 	
223
-	[newVc.getLeafViewController waitForReactViewRender:newVc.getLeafViewController.options.animations.showModal.waitForRender perform:^{
224
-		[_modalManager showModal:newVc animated:newVc.getLeafViewController.options.animations.showModal.enable hasCustomAnimation:newVc.getLeafViewController.options.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
234
+	[newVc.getCurrentChild waitForReactViewRender:newVc.getCurrentChild.options.animations.showModal.waitForRender perform:^{
235
+		[_modalManager showModal:newVc animated:newVc.getCurrentChild.options.animations.showModal.enable hasCustomAnimation:newVc.getCurrentChild.options.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
225 236
 			[_eventEmitter sendOnNavigationCommandCompletion:showModal params:@{@"layout": layout}];
226 237
 			completion(componentId);
227 238
 		}];
228 239
 	}];
229 240
 }
230 241
 
231
-- (void)dismissModal:(NSString*)componentId mergeOptions:(NSDictionary *)options completion:(RNNTransitionCompletionBlock)completion {
242
+- (void)dismissModal:(NSString*)componentId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion {
232 243
 	[self assertReady];
233 244
 	
234 245
 	[CATransaction begin];
@@ -236,7 +247,8 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
236 247
 		[_eventEmitter sendOnNavigationCommandCompletion:dismissModal params:@{@"componentId": componentId}];
237 248
 	}];
238 249
 	UIViewController<RNNParentProtocol> *modalToDismiss = (UIViewController<RNNParentProtocol>*)[_store findComponentForId:componentId];
239
-	[modalToDismiss.getLeafViewController.options mergeWith:options];
250
+	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
251
+	[modalToDismiss.getCurrentChild.options overrideOptions:options];
240 252
 	
241 253
 	[self removePopedViewControllers:modalToDismiss.navigationController.viewControllers];
242 254
 	

+ 3
- 3
lib/ios/RNNComponentOptions.h View File

@@ -2,8 +2,8 @@
2 2
 
3 3
 @interface RNNComponentOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSString* name;
6
-@property (nonatomic, strong) NSString* componentId;
7
-@property (nonatomic, strong) NSString* alignment;
5
+@property (nonatomic, strong) Text* name;
6
+@property (nonatomic, strong) Text* componentId;
7
+@property (nonatomic, strong) Text* alignment;
8 8
 
9 9
 @end

+ 10
- 0
lib/ios/RNNComponentOptions.m View File

@@ -2,4 +2,14 @@
2 2
 
3 3
 @implementation RNNComponentOptions
4 4
 
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
7
+	
8
+	self.name = [TextParser parse:dict key:@"name"];
9
+	self.componentId = [TextParser parse:dict key:@"componentId"];
10
+	self.alignment = [TextParser parse:dict key:@"alignment"];
11
+	
12
+	return self;
13
+}
14
+
5 15
 @end

+ 2
- 2
lib/ios/RNNControllerFactory.h View File

@@ -5,7 +5,6 @@
5 5
 #import "RNNStore.h"
6 6
 #import "RNNEventEmitter.h"
7 7
 #import "RNNParentProtocol.h"
8
-#import "RNNOptionsManager.h"
9 8
 
10 9
 @interface RNNControllerFactory : NSObject
11 10
 
@@ -17,6 +16,7 @@
17 16
 -(UIViewController<RNNParentProtocol, UIViewControllerPreviewingDelegate> *)createLayoutAndSaveToStore:(NSDictionary*)layout;
18 17
 
19 18
 @property (nonatomic, strong) RNNEventEmitter *eventEmitter;
20
-@property (nonatomic, strong) RNNOptionsManager *optionsManager;
19
+
20
+@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
21 21
 
22 22
 @end

+ 26
- 16
lib/ios/RNNControllerFactory.m View File

@@ -8,10 +8,12 @@
8 8
 #import "RNNTabBarController.h"
9 9
 #import "RNNTopTabsViewController.h"
10 10
 #import "RNNLayoutInfo.h"
11
-#import "RNNOptionsManager.h"
11
+#import "RNNRootViewController.h"
12
+#import "UIViewController+SideMenuController.h"
12 13
 #import "RNNViewControllerPresenter.h"
14
+#import "RNNNavigationControllerPresenter.h"
13 15
 #import "RNNTabBarPresenter.h"
14
-#import "RNNRootViewController.h"
16
+#import "RNNSideMenuPresenter.h"
15 17
 
16 18
 @implementation RNNControllerFactory {
17 19
 	id<RNNRootViewCreator> _creator;
@@ -33,7 +35,6 @@
33 35
 	_store = store;
34 36
 	_eventEmitter = eventEmitter;
35 37
 	_bridge = bridge;
36
-	_optionsManager = [RNNOptionsManager new];
37 38
 	
38 39
 	return self;
39 40
 }
@@ -100,9 +101,11 @@
100 101
 
101 102
 - (UIViewController<RNNParentProtocol> *)createComponent:(RNNLayoutNode*)node {
102 103
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
103
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
104
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
104 105
 	
105 106
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
107
+	[presenter setDefaultOptions:_defaultOptions];
108
+	
106 109
 	RNNRootViewController* component = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options];
107 110
 	
108 111
 	if (!component.isExternalViewController) {
@@ -115,9 +118,10 @@
115 118
 
116 119
 - (UIViewController<RNNParentProtocol> *)createExternalComponent:(RNNLayoutNode*)node {
117 120
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
118
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
121
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
119 122
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
120
-
123
+	[presenter setDefaultOptions:_defaultOptions];
124
+	
121 125
 	UIViewController* externalVC = [_store getExternalComponent:layoutInfo bridge:_bridge];
122 126
 	
123 127
 	RNNRootViewController* component = [[RNNRootViewController alloc] initExternalComponentWithLayoutInfo:layoutInfo eventEmitter:_eventEmitter presenter:presenter options:options];
@@ -129,8 +133,10 @@
129 133
 
130 134
 - (UIViewController<RNNParentProtocol> *)createStack:(RNNLayoutNode*)node {
131 135
 	RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] init];
136
+	[presenter setDefaultOptions:_defaultOptions];
137
+	
132 138
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
133
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
139
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
134 140
 	
135 141
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
136 142
 	
@@ -141,8 +147,9 @@
141 147
 
142 148
 -(UIViewController<RNNParentProtocol> *)createTabs:(RNNLayoutNode*)node {
143 149
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
144
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
150
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
145 151
 	RNNTabBarPresenter* presenter = [[RNNTabBarPresenter alloc] init];
152
+	[presenter setDefaultOptions:_defaultOptions];
146 153
 
147 154
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
148 155
 	
@@ -153,8 +160,9 @@
153 160
 
154 161
 - (UIViewController<RNNParentProtocol> *)createTopTabs:(RNNLayoutNode*)node {
155 162
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
156
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
157
-	RNNBasePresenter* presenter = [[RNNBasePresenter alloc] init];
163
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
164
+	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
165
+	[presenter setDefaultOptions:_defaultOptions];
158 166
 
159 167
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
160 168
 	
@@ -165,8 +173,9 @@
165 173
 
166 174
 - (UIViewController<RNNParentProtocol> *)createSideMenu:(RNNLayoutNode*)node {
167 175
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
168
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
169
-	RNNBasePresenter* presenter = [[RNNBasePresenter alloc] init];
176
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
177
+	RNNSideMenuPresenter* presenter = [[RNNSideMenuPresenter alloc] init];
178
+	[presenter setDefaultOptions:_defaultOptions];
170 179
 
171 180
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
172 181
 	
@@ -179,17 +188,18 @@
179 188
 - (UIViewController<RNNParentProtocol> *)createSideMenuChild:(RNNLayoutNode*)node type:(RNNSideMenuChildType)type {
180 189
 	UIViewController<RNNParentProtocol>* childVc = [self fromTree:node.children[0]];
181 190
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
182
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
191
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
183 192
 
184
-	RNNSideMenuChildVC *sideMenuChild = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:layoutInfo childViewControllers:@[childVc] options:options presenter:[[RNNBasePresenter alloc] init] type:type];
193
+	RNNSideMenuChildVC *sideMenuChild = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:layoutInfo childViewControllers:@[childVc] options:options presenter:[[RNNViewControllerPresenter alloc] init] type:type];
185 194
 	
186 195
 	return sideMenuChild;
187 196
 }
188 197
 
189 198
 - (UIViewController<RNNParentProtocol> *)createSplitView:(RNNLayoutNode*)node {
190 199
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
191
-	RNNNavigationOptions* options = [_optionsManager createOptions:node.data[@"options"]];
192
-	RNNBasePresenter* presenter = [[RNNBasePresenter alloc] init];
200
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
201
+	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
202
+	[presenter setDefaultOptions:_defaultOptions];
193 203
 
194 204
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
195 205
 

+ 8
- 0
lib/ios/RNNDefaultOptionsHelper.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import "RNNLayoutProtocol.h"
3
+
4
+@interface RNNDefaultOptionsHelper : NSObject
5
+
6
++ (void)recrusivelySetDefaultOptions:(RNNNavigationOptions *)defaultOptions onRootViewController:(UIViewController *)rootViewController;
7
+
8
+@end

+ 18
- 0
lib/ios/RNNDefaultOptionsHelper.m View File

@@ -0,0 +1,18 @@
1
+#import "RNNDefaultOptionsHelper.h"
2
+
3
+@implementation RNNDefaultOptionsHelper
4
+
5
++ (void)recrusivelySetDefaultOptions:(RNNNavigationOptions *)defaultOptions onRootViewController:(UIViewController *)rootViewController {
6
+	if ([rootViewController conformsToProtocol:@protocol(RNNLayoutProtocol)])
7
+		[((UIViewController<RNNLayoutProtocol> *)rootViewController).presenter setDefaultOptions:defaultOptions];
8
+	
9
+	for (UIViewController<RNNLayoutProtocol>* childViewController in rootViewController.childViewControllers) {
10
+		if ([childViewController conformsToProtocol:@protocol(RNNLayoutProtocol)]) {
11
+			[childViewController.presenter setDefaultOptions:defaultOptions];
12
+		}
13
+		
14
+		[self recrusivelySetDefaultOptions:defaultOptions onRootViewController:childViewController];
15
+	}
16
+}
17
+
18
+@end

+ 8
- 0
lib/ios/RNNFontAttributesCreator.h View File

@@ -0,0 +1,8 @@
1
+#import <Foundation/Foundation.h>
2
+#import <UIKit/UIKit.h>
3
+
4
+@interface RNNFontAttributesCreator : NSObject
5
+
6
++ (NSDictionary *)createFontAttributesWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize color:(UIColor *)color;
7
+
8
+@end

+ 25
- 0
lib/ios/RNNFontAttributesCreator.m View File

@@ -0,0 +1,25 @@
1
+#import "RNNFontAttributesCreator.h"
2
+
3
+@implementation RNNFontAttributesCreator
4
+
5
++ (NSDictionary *)createFontAttributesWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize color:(UIColor *)color {
6
+	NSMutableDictionary* titleTextAttributes = [NSMutableDictionary new];
7
+	if (fontFamily || fontSize || color) {
8
+		if (color) {
9
+			titleTextAttributes[NSForegroundColorAttributeName] = color;
10
+		}
11
+		if (fontFamily){
12
+			if (fontSize) {
13
+				titleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:fontFamily size:[fontSize floatValue]];
14
+			} else {
15
+				titleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:fontFamily size:17];
16
+			}
17
+		} else if (fontSize) {
18
+			titleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:[fontSize floatValue]];
19
+		}
20
+	}
21
+	
22
+	return titleTextAttributes;
23
+}
24
+
25
+@end

+ 5
- 4
lib/ios/RNNLargeTitleOptions.h View File

@@ -3,8 +3,9 @@
3 3
 
4 4
 @interface RNNLargeTitleOptions : RNNOptions
5 5
 
6
-@property (nonatomic, strong) NSNumber* fontSize;
7
-@property (nonatomic, strong) NSNumber* visible;
8
-@property (nonatomic, strong) NSNumber* color;
9
-@property (nonatomic, strong) NSString* fontFamily;
6
+@property (nonatomic, strong) Number* fontSize;
7
+@property (nonatomic, strong) Bool* visible;
8
+@property (nonatomic, strong) Color* color;
9
+@property (nonatomic, strong) Text* fontFamily;
10
+
10 11
 @end

+ 7
- 40
lib/ios/RNNLargeTitleOptions.m View File

@@ -1,49 +1,16 @@
1 1
 #import "RNNLargeTitleOptions.h"
2
-#import "RNNTitleViewHelper.h"
3
-
4 2
 
5 3
 @implementation RNNLargeTitleOptions
6 4
 
7
-- (void)applyOn:(UIViewController *)viewController {
8
-
9
-	if (@available(iOS 11.0, *)) {
10
-		
11
-		viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
5
+- (instancetype)initWithDict:(NSDictionary *)dict {
6
+	self = [super init];
12 7
 	
13
-		if ([self.visible boolValue]){
14
-			viewController.navigationController.navigationBar.prefersLargeTitles = YES;
15
-			viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
16
-		} else {
17
-			viewController.navigationController.navigationBar.prefersLargeTitles = NO;
18
-		}
19
-		
20
-		NSDictionary* fontAttributes = [self fontAttributes];
21
-		viewController.navigationController.navigationBar.largeTitleTextAttributes = fontAttributes;
22
-	}
23
-}
24
-
25
-- (NSDictionary *)fontAttributes {
26
-	NSMutableDictionary* navigationBarTitleTextAttributes = [NSMutableDictionary new];
27
-	if (self.fontFamily || self.fontSize || self.color) {
28
-		if (self.color) {
29
-			navigationBarTitleTextAttributes[NSForegroundColorAttributeName] = [RCTConvert UIColor:self.color];
30
-		}
31
-		if (self.fontFamily){
32
-			if (self.fontSize) {
33
-				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.fontFamily size:[self.fontSize floatValue]];
34
-			} else {
35
-				navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:self.fontFamily size:20];
36
-			}
37
-		} else if (self.fontSize) {
38
-			navigationBarTitleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:[self.fontSize floatValue]];
39
-		}
40
-	}
8
+	self.fontSize = [NumberParser parse:dict key:@"fontSize"];
9
+	self.visible = [BoolParser parse:dict key:@"visible"];
10
+	self.color = [ColorParser parse:dict key:@"color"];
11
+	self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
41 12
 	
42
-	return navigationBarTitleTextAttributes;
43
-}
44
-
45
-- (NSNumber *)fontSize {
46
-	return _fontSize ? _fontSize : nil;
13
+	return self;
47 14
 }
48 15
 
49 16
 @end

+ 0
- 1
lib/ios/RNNLayoutInfo.h View File

@@ -1,5 +1,4 @@
1 1
 #import <Foundation/Foundation.h>
2
-#import "RNNOptionsManager.h"
3 2
 #import "RNNLayoutNode.h"
4 3
 
5 4
 @interface RNNLayoutInfo : NSObject

+ 1
- 1
lib/ios/RNNLayoutOptions.h View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 @interface RNNLayoutOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSNumber* backgroundColor;
5
+@property (nonatomic, strong) Color* backgroundColor;
6 6
 @property (nonatomic, strong) id orientation;
7 7
 
8 8
 - (UIInterfaceOrientationMask)supportedOrientations;

+ 8
- 5
lib/ios/RNNLayoutOptions.m View File

@@ -1,13 +1,16 @@
1 1
 #import "RNNLayoutOptions.h"
2 2
 #import <React/RCTConvert.h>
3
+#import "UIViewController+RNNOptions.h"
3 4
 
4 5
 @implementation RNNLayoutOptions
5 6
 
6
-- (void)applyOn:(UIViewController *)viewController {
7
-	if (self.backgroundColor) {
8
-		UIColor* screenColor = [RCTConvert UIColor:self.backgroundColor];
9
-		viewController.view.backgroundColor = screenColor;
10
-	}
7
+- (instancetype)initWithDict:(NSDictionary *)dict {
8
+	self = [super init];
9
+	
10
+	self.backgroundColor = [ColorParser parse:dict key:@"backgroundColor"];
11
+	self.orientation = dict[@"orientation"];
12
+	
13
+	return self;
11 14
 }
12 15
 
13 16
 - (UIInterfaceOrientationMask)supportedOrientations {

+ 6
- 2
lib/ios/RNNLayoutProtocol.h View File

@@ -1,5 +1,5 @@
1 1
 #import "RNNLayoutInfo.h"
2
-#import "RNNBasePresenter.h"
2
+#import "RNNViewControllerPresenter.h"
3 3
 #import "RNNLeafProtocol.h"
4 4
 
5 5
 @protocol RNNLayoutProtocol <NSObject, UINavigationControllerDelegate, UIViewControllerTransitioningDelegate, UISplitViewControllerDelegate>
@@ -10,6 +10,10 @@
10 10
 @property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
11 11
 @property (nonatomic, strong) RNNNavigationOptions* options;
12 12
 
13
-- (UIViewController<RNNLeafProtocol, RNNLayoutProtocol> *)getLeafViewController;
13
+- (UIViewController<RNNLeafProtocol, RNNLayoutProtocol> *)getCurrentChild;
14
+
15
+- (void)mergeOptions:(RNNNavigationOptions *)options;
16
+
17
+- (RNNNavigationOptions *)resolveOptions;
14 18
 
15 19
 @end

+ 0
- 2
lib/ios/RNNLeafProtocol.h View File

@@ -7,6 +7,4 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
7 7
 
8 8
 - (void)bindViewController:(UIViewController *)viewController;
9 9
 
10
-- (void)mergeAndPresentOptions:(RNNNavigationOptions *)newOptions;
11
-
12 10
 @end

+ 2
- 2
lib/ios/RNNModalManager.m View File

@@ -60,7 +60,7 @@
60 60
 
61 61
 -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion {
62 62
 	UIViewController<RNNParentProtocol> *modalToDismiss = [_pendingModalIdsToDismiss lastObject];
63
-	RNNNavigationOptions* options = modalToDismiss.getLeafViewController.options;
63
+	RNNNavigationOptions* options = modalToDismiss.getCurrentChild.options;
64 64
 
65 65
 	if(!modalToDismiss) {
66 66
 		return;
@@ -88,7 +88,7 @@
88 88
 	} else {
89 89
 		[modalToDismiss.view removeFromSuperview];
90 90
 		modalToDismiss.view = nil;
91
-		modalToDismiss.getLeafViewController.options.animations.dismissModal.enable = NO;
91
+		modalToDismiss.getCurrentChild.options.animations.dismissModal.enable = NO;
92 92
 		[self dismissedModal:modalToDismiss];
93 93
 		
94 94
 		if (completion) {

+ 12
- 12
lib/ios/RNNNavigationButtons.m View File

@@ -70,10 +70,10 @@
70 70
 		@throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil];
71 71
 	}
72 72
 	
73
-	UIImage* iconImage = nil;
74
-	id icon = [self getValue:dictionary[@"icon"] withDefault:defaultStyle.icon];
75
-	if (icon) {
76
-		iconImage = [RCTConvert UIImage:icon];
73
+	UIImage* defaultIcon = [defaultStyle.icon getWithDefaultValue:nil];
74
+	UIImage* iconImage = [self getValue:dictionary[@"icon"] withDefault:defaultIcon];
75
+	if (![iconImage isKindOfClass:[UIImage class]]) {
76
+		iconImage = [RCTConvert UIImage:iconImage];
77 77
 	}
78 78
 	
79 79
 	RNNUIBarButtonItem *barButtonItem;
@@ -96,15 +96,15 @@
96 96
 	barButtonItem.target = self.viewController;
97 97
 	barButtonItem.action = @selector(onButtonPress:);
98 98
 	
99
-	NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled];
99
+	NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled.getValue];
100 100
 	BOOL enabledBool = enabled ? [enabled boolValue] : YES;
101 101
 	[barButtonItem setEnabled:enabledBool];
102 102
 	
103 103
 	NSMutableDictionary* textAttributes = [[NSMutableDictionary alloc] init];
104 104
 	NSMutableDictionary* disabledTextAttributes = [[NSMutableDictionary alloc] init];
105 105
 	
106
-	UIColor* color = [self color:dictionary[@"color"] defaultColor:defaultStyle.color];
107
-	UIColor* disabledColor = [self color:dictionary[@"disabledColor"] defaultColor:defaultStyle.disabledColor];
106
+	UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
107
+	UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]];
108 108
 	if (!enabledBool && disabledColor) {
109 109
 		color = disabledColor;
110 110
 		[disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName];
@@ -115,8 +115,8 @@
115 115
 		[barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
116 116
 	}
117 117
 	
118
-	NSNumber* fontSize = [self fontSize:dictionary[@"fontSize"] defaultFontSize:defaultStyle.fontSize];
119
-	NSString* fontFamily = [self fontFamily:dictionary[@"fontFamily"] defaultFontFamily:defaultStyle.fontFamily];
118
+	NSNumber* fontSize = [self fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:nil]];
119
+	NSString* fontFamily = [self fontFamily:dictionary[@"fontFamily"] defaultFontFamily:[defaultStyle.fontFamily getWithDefaultValue:nil]];
120 120
 	UIFont *font = nil;
121 121
 	if (fontFamily) {
122 122
 		font = [UIFont fontWithName:fontFamily size:[fontSize floatValue]];
@@ -139,11 +139,11 @@
139 139
 	return barButtonItem;
140 140
 }
141 141
 
142
-- (UIColor *)color:(NSNumber *)color defaultColor:(NSNumber *)defaultColor {
142
+- (UIColor *)color:(UIColor *)color defaultColor:(UIColor *)defaultColor {
143 143
 	if (color) {
144
-		return [RCTConvert UIColor:color];
144
+		return color;
145 145
 	} else if (defaultColor) {
146
-		return [RCTConvert UIColor:defaultColor];
146
+		return defaultColor;
147 147
 	}
148 148
 	
149 149
 	return nil;

+ 3
- 0
lib/ios/RNNNavigationController.h View File

@@ -1,6 +1,7 @@
1 1
 #import <UIKit/UIKit.h>
2 2
 #import "RNNParentProtocol.h"
3 3
 #import "RNNNavigationControllerPresenter.h"
4
+#import "UINavigationController+RNNOptions.h"
4 5
 
5 6
 @interface RNNNavigationController : UINavigationController <RNNParentProtocol>
6 7
 
@@ -8,4 +9,6 @@
8 9
 @property (nonatomic, retain) RNNNavigationControllerPresenter* presenter;
9 10
 @property (nonatomic, strong) RNNNavigationOptions* options;
10 11
 
12
+- (void)setTopBarBackgroundColor:(UIColor *)backgroundColor;
13
+
11 14
 @end

+ 88
- 8
lib/ios/RNNNavigationController.m View File

@@ -3,13 +3,23 @@
3 3
 #import "RNNModalAnimation.h"
4 4
 #import "RNNRootViewController.h"
5 5
 
6
+const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
7
+
8
+@interface RNNNavigationController()
9
+
10
+@property (nonatomic, strong) NSMutableDictionary* originalTopBarImages;
11
+
12
+@end
13
+
6 14
 @implementation RNNNavigationController
7 15
 
8 16
 - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNNavigationControllerPresenter *)presenter {
9 17
 	self = [super init];
10 18
 
11 19
 	self.presenter = presenter;
20
+	[self.presenter bindViewController:self];
12 21
 	self.options = options;
22
+	
13 23
 	self.layoutInfo = layoutInfo;
14 24
 	
15 25
 	[self setViewControllers:childViewControllers];
@@ -17,6 +27,30 @@
17 27
 	return self;
18 28
 }
19 29
 
30
+- (void)willMoveToParentViewController:(UIViewController *)parent {
31
+	if (parent) {
32
+		[_presenter applyOptionsOnWillMoveToParentViewController:self.options];
33
+	}
34
+}
35
+
36
+- (void)onChildWillAppear {
37
+	[_presenter applyOptions:self.resolveOptions];
38
+	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
39
+}
40
+
41
+- (RNNNavigationOptions *)resolveOptions {
42
+	return (RNNNavigationOptions *)[self.getCurrentChild.resolveOptions.copy mergeOptions:self.options];
43
+}
44
+
45
+- (void)mergeOptions:(RNNNavigationOptions *)options {
46
+	[_presenter mergeOptions:options];
47
+	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
48
+}
49
+
50
+- (UITabBarItem *)tabBarItem {
51
+	return super.tabBarItem ? super.tabBarItem : self.viewControllers.lastObject.tabBarItem;
52
+}
53
+
20 54
 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
21 55
 	return self.viewControllers.lastObject.supportedInterfaceOrientations;
22 56
 }
@@ -26,11 +60,11 @@
26 60
 }
27 61
 
28 62
 - (UIStatusBarStyle)preferredStatusBarStyle {
29
-	return self.getLeafViewController.preferredStatusBarStyle;
63
+	return self.getCurrentChild.preferredStatusBarStyle;
30 64
 }
31 65
 
32 66
 - (UIModalPresentationStyle)modalPresentationStyle {
33
-	return self.getLeafViewController.modalPresentationStyle;
67
+	return self.getCurrentChild.modalPresentationStyle;
34 68
 }
35 69
 
36 70
 - (UIViewController *)popViewControllerAnimated:(BOOL)animated {
@@ -38,7 +72,7 @@
38 72
 		UIViewController *controller = self.viewControllers[self.viewControllers.count - 2];
39 73
 		if ([controller isKindOfClass:[RNNRootViewController class]]) {
40 74
 			RNNRootViewController *rnnController = (RNNRootViewController *)controller;
41
-			[rnnController.presenter present:rnnController.options onViewControllerDidLoad:rnnController];
75
+			[self.presenter applyOptions:rnnController.options];
42 76
 		}
43 77
 	}
44 78
 	
@@ -46,14 +80,14 @@
46 80
 }
47 81
 
48 82
 - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
49
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getLeafViewController.options.animations.showModal isDismiss:NO];
83
+	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getCurrentChild.options.animations.showModal isDismiss:NO];
50 84
 }
51 85
 
52 86
 - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
53
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getLeafViewController.options.animations.dismissModal isDismiss:YES];
87
+	return [[RNNModalAnimation alloc] initWithScreenTransition:self.getCurrentChild.options.animations.dismissModal isDismiss:YES];
54 88
 }
55 89
 
56
-- (UIViewController *)getLeafViewController {
90
+- (UIViewController *)getCurrentChild {
57 91
 	return ((UIViewController<RNNParentProtocol>*)self.topViewController);
58 92
 }
59 93
 
@@ -61,8 +95,54 @@
61 95
 	return self.topViewController;
62 96
 }
63 97
 
64
-- (void)willMoveToParentViewController:(UIViewController *)parent {
65
-	[_presenter present:self.options onViewControllerDidLoad:self];
98
+- (void)setTopBarBackgroundColor:(UIColor *)backgroundColor {
99
+	if (backgroundColor) {
100
+		CGFloat bgColorAlpha = CGColorGetAlpha(backgroundColor.CGColor);
101
+		
102
+		if (bgColorAlpha == 0.0) {
103
+			if (![self.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG]){
104
+				[self storeOriginalTopBarImages:self];
105
+				UIView *transparentView = [[UIView alloc] initWithFrame:CGRectZero];
106
+				transparentView.backgroundColor = [UIColor clearColor];
107
+				transparentView.tag = TOP_BAR_TRANSPARENT_TAG;
108
+				[self.navigationBar insertSubview:transparentView atIndex:0];
109
+			}
110
+			self.navigationBar.translucent = YES;
111
+			[self.navigationBar setBackgroundColor:[UIColor clearColor]];
112
+			self.navigationBar.shadowImage = [UIImage new];
113
+			[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
114
+		} else {
115
+			self.navigationBar.barTintColor = backgroundColor;
116
+			UIView *transparentView = [self.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG];
117
+			if (transparentView){
118
+				[transparentView removeFromSuperview];
119
+				[self.navigationBar setBackgroundImage:self.originalTopBarImages[@"backgroundImage"] forBarMetrics:UIBarMetricsDefault];
120
+				self.navigationBar.shadowImage = self.originalTopBarImages[@"shadowImage"];
121
+				self.originalTopBarImages = nil;
122
+			}
123
+		}
124
+	} else {
125
+		UIView *transparentView = [self.navigationBar viewWithTag:TOP_BAR_TRANSPARENT_TAG];
126
+		if (transparentView){
127
+			[transparentView removeFromSuperview];
128
+			[self.navigationBar setBackgroundImage:self.originalTopBarImages[@"backgroundImage"] forBarMetrics:UIBarMetricsDefault];
129
+			self.navigationBar.shadowImage = self.originalTopBarImages[@"shadowImage"];
130
+			self.originalTopBarImages = nil;
131
+		}
132
+	}
133
+}
134
+
135
+- (void)storeOriginalTopBarImages:(UINavigationController *)navigationController {
136
+	NSMutableDictionary *originalTopBarImages = [@{} mutableCopy];
137
+	UIImage *bgImage = [navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
138
+	if (bgImage != nil) {
139
+		originalTopBarImages[@"backgroundImage"] = bgImage;
140
+	}
141
+	UIImage *shadowImage = navigationController.navigationBar.shadowImage;
142
+	if (shadowImage != nil) {
143
+		originalTopBarImages[@"shadowImage"] = shadowImage;
144
+	}
145
+	self.originalTopBarImages = originalTopBarImages;
66 146
 }
67 147
 
68 148
 

+ 0
- 2
lib/ios/RNNNavigationControllerPresenter.h View File

@@ -1,7 +1,5 @@
1
-#import <Foundation/Foundation.h>
2 1
 #import "RNNBasePresenter.h"
3 2
 
4 3
 @interface RNNNavigationControllerPresenter : RNNBasePresenter
5 4
 
6
-
7 5
 @end

+ 87
- 4
lib/ios/RNNNavigationControllerPresenter.m View File

@@ -1,13 +1,96 @@
1 1
 #import "RNNNavigationControllerPresenter.h"
2
+#import "UINavigationController+RNNOptions.h"
3
+#import "RNNNavigationController.h"
2 4
 
3 5
 @implementation RNNNavigationControllerPresenter
4 6
 
5
-- (void)present:(RNNNavigationOptions *)options onViewControllerDidLoad:(UINavigationController *)navigationController {
6
-	[options applyOnNavigationController:navigationController];
7
+- (void)applyOptions:(RNNNavigationOptions *)initialOptions {
8
+	[super applyOptions:initialOptions];
9
+	RNNNavigationOptions* options = [initialOptions withDefault:self.defaultOptions];
10
+	
11
+	
12
+	RNNNavigationController* navigationController = self.bindedViewController;
13
+
14
+	[navigationController rnn_setInteractivePopGestureEnabled:[options.popGesture getWithDefaultValue:YES]];
15
+	[navigationController rnn_setRootBackgroundImage:[options.rootBackgroundImage getWithDefaultValue:nil]];
16
+	[navigationController rnn_setNavigationBarTestID:[options.topBar.testID getWithDefaultValue:nil]];
17
+	[navigationController rnn_setNavigationBarVisible:[options.topBar.visible getWithDefaultValue:YES] animated:[options.topBar.animate getWithDefaultValue:YES]];
18
+	[navigationController rnn_hideBarsOnScroll:[options.topBar.hideOnScroll getWithDefaultValue:NO]];
19
+	[navigationController rnn_setNavigationBarNoBorder:[options.topBar.noBorder getWithDefaultValue:NO]];
20
+	[navigationController rnn_setBarStyle:[RCTConvert UIBarStyle:[options.topBar.barStyle getWithDefaultValue:@"default"]]];
21
+	[navigationController rnn_setNavigationBarTranslucent:[options.topBar.background.translucent getWithDefaultValue:NO]];
22
+	[navigationController rnn_setNavigationBarClipsToBounds:[options.topBar.background.clipToBounds getWithDefaultValue:NO]];
23
+	[navigationController rnn_setNavigationBarBlur:[options.topBar.background.blur getWithDefaultValue:NO]];
24
+	[navigationController setTopBarBackgroundColor:[options.topBar.background.color getWithDefaultValue:nil]];
25
+	[navigationController rnn_setNavigationBarLargeTitleVisible:[options.topBar.largeTitle.visible getWithDefaultValue:NO]];
26
+	[navigationController rnn_setNavigationBarLargeTitleFontFamily:[options.topBar.largeTitle.fontFamily getWithDefaultValue:nil] fontSize:[options.topBar.largeTitle.fontSize getWithDefaultValue:nil] color:[options.topBar.largeTitle.color getWithDefaultValue:nil]];
27
+	[navigationController rnn_setBackButtonIcon:[options.topBar.backButton.icon getWithDefaultValue:nil] withColor:[options.topBar.backButton.color getWithDefaultValue:nil] title:[options.topBar.backButton.showTitle getWithDefaultValue:YES] ? [options.topBar.backButton.title getWithDefaultValue:nil] : @""];
28
+	[navigationController rnn_setNavigationBarFontFamily:[options.topBar.title.fontFamily getWithDefaultValue:nil] fontSize:[options.topBar.title.fontSize getWithDefaultValue:nil] color:[options.topBar.title.color getWithDefaultValue:nil]];
7 29
 }
8 30
 
9
-- (void)present:(RNNNavigationOptions *)options onViewControllerWillAppear:(UINavigationController *)navigationController {
10
-	[options applyOnNavigationController:navigationController];
31
+- (void)mergeOptions:(RNNNavigationOptions *)options {
32
+	[super mergeOptions:options];
33
+	
34
+	RNNNavigationController* navigationController = self.bindedViewController;
35
+	RNNNavigationOptions* withDefault = (RNNNavigationOptions *)[options withDefault:self.defaultOptions];
36
+	
37
+	if (options.popGesture.hasValue) {
38
+		[navigationController rnn_setInteractivePopGestureEnabled:withDefault.popGesture.get];
39
+	}
40
+	
41
+	if (options.rootBackgroundImage.hasValue) {
42
+		[navigationController rnn_setRootBackgroundImage:withDefault.rootBackgroundImage.get];
43
+	}
44
+	
45
+	if (options.topBar.testID.hasValue) {
46
+		[navigationController rnn_setNavigationBarTestID:withDefault.topBar.testID.get];
47
+	}
48
+	
49
+	if (options.topBar.visible.hasValue) {
50
+		[navigationController rnn_setNavigationBarVisible:withDefault.topBar.visible.get animated:[withDefault.topBar.animate getWithDefaultValue:YES]];
51
+	}
52
+	
53
+	if (options.topBar.hideOnScroll.hasValue) {
54
+		[navigationController rnn_hideBarsOnScroll:[withDefault.topBar.hideOnScroll get]];
55
+	}
56
+	
57
+	if (options.topBar.noBorder.hasValue) {
58
+		[navigationController rnn_setNavigationBarNoBorder:[withDefault.topBar.noBorder get]];
59
+	}
60
+	
61
+	if (options.topBar.barStyle.hasValue) {
62
+		[navigationController rnn_setBarStyle:[RCTConvert UIBarStyle:withDefault.topBar.barStyle.get]];
63
+	}
64
+	
65
+	if (options.topBar.background.translucent.hasValue) {
66
+		[navigationController rnn_setNavigationBarTranslucent:[withDefault.topBar.background.translucent get]];
67
+	}
68
+	
69
+	if (options.topBar.background.clipToBounds.hasValue) {
70
+		[navigationController rnn_setNavigationBarClipsToBounds:[withDefault.topBar.background.clipToBounds get]];
71
+	}
72
+	
73
+	if (options.topBar.background.blur.hasValue) {
74
+		[navigationController rnn_setNavigationBarBlur:[withDefault.topBar.background.blur get]];
75
+	}
76
+	
77
+	if (options.topBar.background.color.hasValue) {
78
+		[navigationController setTopBarBackgroundColor:withDefault.topBar.background.color.get];
79
+	}
80
+	
81
+	if (options.topBar.largeTitle.visible.hasValue) {
82
+		[navigationController rnn_setNavigationBarLargeTitleVisible:withDefault.topBar.largeTitle.visible.get];
83
+	}
84
+	
85
+	if (options.topBar.backButton.icon.hasValue) {
86
+		[navigationController rnn_setBackButtonIcon:[withDefault.topBar.backButton.icon getWithDefaultValue:nil] withColor:[withDefault.topBar.backButton.color getWithDefaultValue:nil] title:[withDefault.topBar.backButton.showTitle getWithDefaultValue:nil] ? withDefault.topBar.backButton.title.get : @""];
87
+
88
+	}
89
+	
90
+	[navigationController rnn_setNavigationBarLargeTitleFontFamily:[withDefault.topBar.largeTitle.fontFamily getWithDefaultValue:nil] fontSize:[withDefault.topBar.largeTitle.fontSize getWithDefaultValue:nil] color:[withDefault.topBar.largeTitle.color getWithDefaultValue:nil]];
91
+	
92
+	[navigationController rnn_setNavigationBarFontFamily:[withDefault.topBar.title.fontFamily getWithDefaultValue:nil] fontSize:[withDefault.topBar.title.fontSize getWithDefaultValue:nil] color:[withDefault.topBar.title.color getWithDefaultValue:nil]];
93
+
11 94
 }
12 95
 
13 96
 @end

+ 11
- 7
lib/ios/RNNNavigationOptions.h View File

@@ -1,4 +1,3 @@
1
-#import <Foundation/Foundation.h>
2 1
 #import "RNNTopBarOptions.h"
3 2
 #import "RNNBottomTabsOptions.h"
4 3
 #import "RNNBottomTabOptions.h"
@@ -31,11 +30,16 @@ extern const NSInteger TOP_BAR_TRANSPARENT_TAG;
31 30
 @property (nonatomic, strong) RNNPreviewOptions* preview;
32 31
 @property (nonatomic, strong) RNNLayoutOptions* layout;
33 32
 
34
-@property (nonatomic, strong) NSMutableDictionary* originalTopBarImages;
35
-@property (nonatomic, strong) NSNumber* popGesture;
36
-@property (nonatomic, strong) NSDictionary* backgroundImage;
37
-@property (nonatomic, strong) NSDictionary* rootBackgroundImage;
38
-@property (nonatomic, strong) NSString* modalPresentationStyle;
39
-@property (nonatomic, strong) NSString* modalTransitionStyle;
33
+@property (nonatomic, strong) Bool* popGesture;
34
+@property (nonatomic, strong) Image* backgroundImage;
35
+@property (nonatomic, strong) Image* rootBackgroundImage;
36
+@property (nonatomic, strong) Text* modalPresentationStyle;
37
+@property (nonatomic, strong) Text* modalTransitionStyle;
38
+
39
+- (instancetype)initEmptyOptions;
40
+
41
+- (RNNNavigationOptions *)withDefault:(RNNNavigationOptions *)defaultOptions;
42
+
43
+- (RNNNavigationOptions *)copy;
40 44
 
41 45
 @end

+ 33
- 57
lib/ios/RNNNavigationOptions.m View File

@@ -7,75 +7,51 @@
7 7
 #import "RNNRootViewController.h"
8 8
 #import "RNNSplitViewController.h"
9 9
 #import "RNNNavigationButtons.h"
10
+#import "UIViewController+RNNOptions.h"
11
+#import "UINavigationController+RNNOptions.h"
10 12
 
11 13
 @implementation RNNNavigationOptions
12 14
 
13
-- (void)applyOn:(UIViewController *)viewController {
14
-	[self.topBar applyOn:viewController];
15
-	[self.bottomTabs applyOn:viewController];
16
-	[self.topTab applyOn:viewController];
17
-	[self.bottomTab applyOn:viewController];
18
-	[self.sideMenu applyOn:viewController];
19
-	[self.overlay applyOn:viewController];
20
-	[self.statusBar applyOn:viewController];
21
-	[self.layout applyOn:viewController];
15
+- (instancetype)initWithDict:(NSDictionary *)dict {
16
+	self = [super init];
22 17
 	
23
-	[self applyOtherOptionsOn:viewController];
18
+	self.topBar = [[RNNTopBarOptions alloc] initWithDict:dict[@"topBar"]];
19
+	self.bottomTabs = [[RNNBottomTabsOptions alloc] initWithDict:dict[@"bottomTabs"]];
20
+	self.bottomTab = [[RNNBottomTabOptions alloc] initWithDict:dict[@"bottomTab"]];
21
+	self.topTabs = [[RNNTopTabsOptions alloc] initWithDict:dict[@"topTabs"]];
22
+	self.topTab = [[RNNTopTabOptions alloc] initWithDict:dict[@"topTab"]];
23
+	self.sideMenu = [[RNNSideMenuOptions alloc] initWithDict:dict[@"sideMenu"]];
24
+	self.overlay = [[RNNOverlayOptions alloc] initWithDict:dict[@"overlay"]];
25
+	self.customTransition = [[RNNAnimationOptions alloc] initWithDict:dict[@"customTransition"]];
26
+	self.animations = [[RNNTransitionsOptions alloc] initWithDict:dict[@"animations"]];
27
+	self.statusBar = [[RNNStatusBarOptions alloc] initWithDict:dict[@"statusBar"]];
28
+	self.preview = [[RNNPreviewOptions alloc] initWithDict:dict[@"preview"]];
29
+	self.layout = [[RNNLayoutOptions alloc] initWithDict:dict[@"layout"]];
24 30
 	
25
-	[self applyOnNavigationController:viewController.navigationController];
26
-	[self applyOnTabBarController:viewController.tabBarController];
27
-}
28
-
29
-- (void)applyOnNavigationController:(UINavigationController *)navigationController {
30
-	[self.topBar applyOnNavigationController:navigationController];
31
-	[self.statusBar applyOn:navigationController];
32
-	[self.layout applyOn:navigationController];
33
-	[self.bottomTab applyOn:navigationController];
34
-	[self applyOtherOptionsOnNavigationController:navigationController];
31
+	self.popGesture = [[Bool alloc] initWithValue:dict[@"popGesture"]];
32
+	
33
+	self.backgroundImage = [ImageParser parse:dict key:@"backgroundImage"];
34
+	self.rootBackgroundImage = [ImageParser parse:dict key:@"rootBackgroundImage"];
35
+	self.modalPresentationStyle = [[Text alloc] initWithValue:dict[@"modalPresentationStyle"]];
36
+	self.modalTransitionStyle = [[Text alloc] initWithValue:dict[@"modalTransitionStyle"]];
37
+	
38
+	return self;
35 39
 }
36 40
 
37
-- (void)applyOnTabBarController:(UITabBarController *)tabBarController {
38
-	[self.bottomTabs applyOnTabBarController:tabBarController];
41
+- (instancetype)initEmptyOptions {
42
+	self = [self initWithDict:@{}];
43
+	return self;
39 44
 }
40 45
 
41
-- (void)applyOtherOptionsOnNavigationController:(UINavigationController*)navigationController {
42
-	if (self.popGesture) {
43
-		navigationController.interactivePopGestureRecognizer.enabled = [self.popGesture boolValue];
44
-	}
46
+- (RNNOptions *)copy {
47
+	RNNNavigationOptions* newOptions = [[RNNNavigationOptions alloc] initWithDict:@{}];
48
+	[newOptions overrideOptions:self];
45 49
 	
46
-	if (self.rootBackgroundImage) {
47
-		UIImageView* backgroundImageView = (navigationController.view.subviews.count > 0) ? navigationController.view.subviews[0] : nil;
48
-		if (![backgroundImageView isKindOfClass:[UIImageView class]]) {
49
-			backgroundImageView = [[UIImageView alloc] initWithFrame:navigationController.view.bounds];
50
-			[navigationController.view insertSubview:backgroundImageView atIndex:0];
51
-		}
52
-		
53
-		backgroundImageView.layer.masksToBounds = YES;
54
-		backgroundImageView.image = [self.rootBackgroundImage isKindOfClass:[UIImage class]] ? (UIImage*)self.rootBackgroundImage : [RCTConvert UIImage:self.rootBackgroundImage];
55
-		[backgroundImageView setContentMode:UIViewContentModeScaleAspectFill];
56
-	}
50
+	return newOptions;
57 51
 }
58 52
 
59
-- (void)applyOtherOptionsOn:(UIViewController*)viewController {
60
-	if (self.backgroundImage) {
61
-		UIImageView* backgroundImageView = (viewController.view.subviews.count > 0) ? viewController.view.subviews[0] : nil;
62
-		if (![backgroundImageView isKindOfClass:[UIImageView class]]) {
63
-			backgroundImageView = [[UIImageView alloc] initWithFrame:viewController.view.bounds];
64
-			[viewController.view insertSubview:backgroundImageView atIndex:0];
65
-		}
66
-		
67
-		backgroundImageView.layer.masksToBounds = YES;
68
-		backgroundImageView.image = [self.backgroundImage isKindOfClass:[UIImage class]] ? (UIImage*)self.backgroundImage : [RCTConvert UIImage:self.backgroundImage];
69
-		[backgroundImageView setContentMode:UIViewContentModeScaleAspectFill];
70
-	}
71
-
72
-	if (self.modalPresentationStyle) {
73
-		viewController.modalPresentationStyle = [RCTConvert UIModalPresentationStyle:self.modalPresentationStyle];
74
-		[viewController.view setBackgroundColor:[UIColor clearColor]];
75
-	}
76
-	if (self.modalTransitionStyle) {
77
-		viewController.modalTransitionStyle = [RCTConvert UIModalTransitionStyle:self.modalTransitionStyle];
78
-	}
53
+- (RNNNavigationOptions *)withDefault:(RNNNavigationOptions *)defaultOptions {
54
+	return (RNNNavigationOptions *)[super withDefault:defaultOptions];
79 55
 }
80 56
 
81 57
 @end

+ 13
- 20
lib/ios/RNNOptions.h View File

@@ -1,28 +1,21 @@
1
-#import <Foundation/Foundation.h>
2 1
 #import <UIKit/UIKit.h>
3 2
 #import <React/RCTConvert.h>
3
+#import "BoolParser.h"
4
+#import "TextParser.h"
5
+#import "NumberParser.h"
6
+#import "DictionaryParser.h"
7
+#import "ColorParser.h"
8
+#import "ImageParser.h"
9
+#import "IntNumberParser.h"
10
+#import "DoubleParser.h"
4 11
 
5
-@class RNNOptions;
12
+@interface RNNOptions : NSObject
6 13
 
7
-@protocol RNNOptionsProtocol <NSObject>
8
-
9
-@optional
10
-- (void)resetOptions;
11
-
12
-@required
13
-- (void)applyOn:(UIViewController *)viewController;
14
-- (void)applyOnNavigationController:(UINavigationController *)navigationController;
15
-- (void)applyOnTabBarController:(UITabBarController *)tabBarController;
16
-
17
-@end
14
+- (instancetype)initWithDict:(NSDictionary*)dict;
18 15
 
19
-@interface RNNOptions : NSObject <RNNOptionsProtocol>
16
+- (RNNOptions *)overrideOptions:(RNNOptions *)otherOptions;
17
+- (RNNOptions *)mergeOptions:(RNNOptions *)otherOptions;
20 18
 
21
-- (instancetype)initWithDict:(NSDictionary*)dict;
22
-- (void)mergeWith:(NSDictionary*)otherOptions;
23
-- (void)applyOn:(UIViewController *)viewController defaultOptions:(RNNOptions*)defaultOptions;
24
-- (BOOL)hasProperty:(NSString*)propName;
25
-- (void)mergeOptions:(RNNOptions *)otherOptions;
26
-- (void)mergeOptions:(RNNOptions *)otherOptions overrideOptions:(BOOL)override;
19
+- (RNNOptions *)withDefault:(RNNOptions *)defaultOptions;
27 20
 
28 21
 @end

+ 17
- 60
lib/ios/RNNOptions.m View File

@@ -6,83 +6,40 @@
6 6
 
7 7
 - (instancetype)initWithDict:(NSDictionary *)dict {
8 8
 	self = [super init];
9
-	[self initializeOptionsPropertiesWithDict:dict];
10
-	
11
-	[self mergeWith:dict];
12 9
 	return self;
13 10
 }
14 11
 
15
-- (void)applyOn:(UIViewController *)viewController defaultOptions:(RNNOptions *)defaultOptions {
16
-	[defaultOptions applyOn:viewController];
17
-	[self applyOn:viewController];
18
-}
19
-
20
-- (void)applyOn:(UIViewController *)viewController {
21
-	
22
-}
23
-
24
-- (void)applyOnNavigationController:(UINavigationController *)navigationController {
25
-	
26
-}
27
-
28
-- (void)applyOnTabBarController:(UITabBarController *)tabBarController {
29
-	
30
-}
31
-
32
-- (void)mergeWith:(NSDictionary *)otherOptions {
33
-	for (id key in otherOptions) {
34
-		if ([self hasProperty:key]) {
35
-			if ([[self valueForKey:key] isKindOfClass:[RNNOptions class]]) {
36
-				RNNOptions* options = [self valueForKey:key];
37
-				[options mergeWith:[otherOptions objectForKey:key]];
38
-			} else {
39
-				[self setValue:[otherOptions objectForKey:key] forKey:key];
40
-			}
41
-		}
42
-	}
43
-}
44
-
45
-- (void)mergeOptions:(RNNOptions *)otherOptions overrideOptions:(BOOL)override {
12
+- (RNNOptions *)mergeOptions:(RNNOptions *)otherOptions overrideOptions:(BOOL)override {
46 13
 	for (id prop in [self objectProperties:otherOptions]) {
47 14
 		id value = [otherOptions valueForKey:prop];
48 15
 		if ([value isKindOfClass:[RNNOptions class]]) {
49 16
 			[[self valueForKey:prop] mergeOptions:value overrideOptions:override];
17
+		} else if ([value isKindOfClass:[Param class]]) {
18
+			if ((((Param *)value).hasValue) && (override || !((Param *)[self valueForKey:prop]).hasValue)) {
19
+				[self setValue:value forKey:prop];
20
+			}
50 21
 		} else if (value && (override || ![self valueForKey:prop])) {
51 22
 			[self setValue:value forKey:prop];
52 23
 		}
53 24
 	}
25
+	
26
+	return self;
54 27
 }
55 28
 
56
-- (void)mergeOptions:(RNNOptions *)otherOptions {
57
-	[self mergeOptions:otherOptions overrideOptions:YES];
29
+- (RNNOptions *)overrideOptions:(RNNOptions *)otherOptions {
30
+	return [self mergeOptions:otherOptions overrideOptions:YES];
58 31
 }
59 32
 
60
-- (BOOL)hasProperty:(NSString*)propName {
61
-	return [self respondsToSelector:NSSelectorFromString(propName)];
33
+- (RNNOptions *)mergeOptions:(RNNOptions *)otherOptions {
34
+	return [self mergeOptions:otherOptions overrideOptions:NO];
62 35
 }
63 36
 
64
-- (void)initializeOptionsPropertiesWithDict:(NSDictionary*)dict {
65
-	unsigned int count;
66
-	objc_property_t* props = class_copyPropertyList([self class], &count);
67
-	for (int i = 0; i < count; i++) {
68
-		objc_property_t property = props[i];
69
-		NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
70
-		const char * type = property_getAttributes(property);
71
-		NSString * typeString = [NSString stringWithUTF8String:type];
72
-		NSArray * attributes = [typeString componentsSeparatedByString:@","];
73
-		NSString * typeAttribute = [attributes objectAtIndex:0];
74
-		
75
-		if ([typeAttribute hasPrefix:@"T@"] && [typeAttribute length] > 3) {
76
-			NSString * typeClassName = [typeAttribute substringWithRange:NSMakeRange(3, [typeAttribute length]-4)];
77
-			Class typeClass = NSClassFromString(typeClassName);
78
-			if ([typeClass isSubclassOfClass:[RNNOptions class]]) {
79
-				RNNOptions* value = [[typeClass alloc] initWithDict:dict[propertyName]];
80
-				[self setValue:value forKey:propertyName];
81
-			}
82
-		}
83
-		
84
-	}
85
-	free(props);
37
+- (RNNOptions *)withDefault:(RNNOptions *)defaultOptions {
38
+	RNNOptions* newOptions = [[[self class] alloc] initWithDict:@{}];
39
+	[newOptions mergeOptions:defaultOptions overrideOptions:YES];
40
+	[newOptions mergeOptions:self overrideOptions:YES];
41
+	
42
+	return newOptions;
86 43
 }
87 44
 
88 45
 - (NSArray *)objectProperties:(NSObject *)object {

+ 0
- 10
lib/ios/RNNOptionsManager.h View File

@@ -1,10 +0,0 @@
1
-#import <Foundation/Foundation.h>
2
-#import "RNNNavigationOptions.h"
3
-
4
-@interface RNNOptionsManager : NSObject
5
-
6
-- (RNNNavigationOptions *)createOptions:(NSDictionary *)optionsDict;
7
-
8
-@property (nonatomic, strong) NSDictionary* defaultOptionsDict;
9
-
10
-@end

+ 0
- 12
lib/ios/RNNOptionsManager.m View File

@@ -1,12 +0,0 @@
1
-#import "RNNOptionsManager.h"
2
-
3
-@implementation RNNOptionsManager
4
-
5
-- (RNNNavigationOptions *)createOptions:(NSDictionary *)optionsDict {
6
-	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:optionsDict];
7
-	
8
-	[options mergeOptions:[[RNNNavigationOptions alloc] initWithDict:_defaultOptionsDict] overrideOptions:NO];
9
-	
10
-	return options;
11
-}
12
-@end

+ 1
- 1
lib/ios/RNNOverlayOptions.h View File

@@ -2,6 +2,6 @@
2 2
 
3 3
 @interface RNNOverlayOptions : RNNOptions
4 4
 
5
-@property (nonatomic, strong) NSNumber* interceptTouchOutside;
5
+@property (nonatomic, strong) Bool* interceptTouchOutside;
6 6
 
7 7
 @end

+ 12
- 4
lib/ios/RNNOverlayOptions.m View File

@@ -3,11 +3,19 @@
3 3
 
4 4
 @implementation RNNOverlayOptions
5 5
 
6
+- (instancetype)initWithDict:(NSDictionary *)dict {
7
+	self = [super init];
8
+	
9
+	self.interceptTouchOutside = [BoolParser parse:dict key:@"interceptTouchOutside"];
10
+	
11
+	return self;
12
+}
13
+
6 14
 - (void)applyOn:(UIViewController *)viewController {
7
-	if (self.interceptTouchOutside) {
8
-		RCTRootView* rootView = (RCTRootView*)viewController.view;
9
-		rootView.passThroughTouches = ![self.interceptTouchOutside boolValue];
10
-	}
15
+//	if (self.interceptTouchOutside) {
16
+//		RCTRootView* rootView = (RCTRootView*)viewController.view;
17
+//		rootView.passThroughTouches = ![self.interceptTouchOutside boolValue];
18
+//	}
11 19
 }
12 20
 
13 21
 @end

+ 2
- 0
lib/ios/RNNParentProtocol.h View File

@@ -7,4 +7,6 @@
7 7
 
8 8
 - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNBasePresenter *)presenter;
9 9
 
10
+- (void)onChildWillAppear;
11
+
10 12
 @end

+ 1
- 1
lib/ios/RNNReactRootViewCreator.m View File

@@ -39,7 +39,7 @@
39 39
 }
40 40
 
41 41
 -(UIView*)createRootViewFromComponentOptions:(RNNComponentOptions*)componentOptions {
42
-	return [self createCustomReactView:componentOptions.name rootViewId:componentOptions.componentId];
42
+	return [self createCustomReactView:componentOptions.name.get rootViewId:componentOptions.componentId.get];
43 43
 }
44 44
 
45 45
 @end

+ 0
- 2
lib/ios/RNNRootViewController.h View File

@@ -1,5 +1,3 @@
1
-#import <Foundation/Foundation.h>
2
-#import <UIKit/UIKit.h>
3 1
 #import "RNNLayoutNode.h"
4 2
 #import "RNNRootViewCreator.h"
5 3
 #import "RNNEventEmitter.h"

+ 71
- 43
lib/ios/RNNRootViewController.m View File

@@ -5,6 +5,7 @@
5 5
 #import "RNNPushAnimation.h"
6 6
 #import "RNNReactView.h"
7 7
 #import "RNNParentProtocol.h"
8
+#import "RNNTitleViewHelper.h"
8 9
 
9 10
 @interface RNNRootViewController() {
10 11
 	RNNReactView* _customTitleView;
@@ -23,14 +24,9 @@
23 24
 
24 25
 - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo rootViewCreator:(id<RNNRootViewCreator>)creator eventEmitter:(RNNEventEmitter *)eventEmitter presenter:(RNNViewControllerPresenter *)presenter options:(RNNNavigationOptions *)options {
25 26
 	self = [super init];
26
-	self.eventEmitter = eventEmitter;
27
-	self.creator = creator;
28
-	self.layoutInfo = layoutInfo;
29
-	self.presenter = presenter;
30
-	self.options = options;
31
-	
32
-	self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.options.customTransition];
33 27
 	
28
+	self.layoutInfo = layoutInfo;
29
+	self.creator = creator;
34 30
 	if (self.creator) {
35 31
 		self.view = [creator createRootView:self.layoutInfo.name rootViewId:self.layoutInfo.componentId];
36 32
 		[[NSNotificationCenter defaultCenter] addObserver:self
@@ -39,6 +35,13 @@
39 35
 												   object:nil];
40 36
 	}
41 37
 	
38
+	self.eventEmitter = eventEmitter;
39
+	self.presenter = presenter;
40
+	[self.presenter bindViewController:self];
41
+	self.options = options;
42
+	
43
+	self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.options.customTransition];
44
+	
42 45
 	[[NSNotificationCenter defaultCenter] addObserver:self
43 46
 											 selector:@selector(onJsReload)
44 47
 												 name:RCTJavaScriptWillStartLoadingNotification
@@ -59,11 +62,31 @@
59 62
 	[viewController didMoveToParentViewController:self];
60 63
 }
61 64
 
65
+- (void)willMoveToParentViewController:(UIViewController *)parent {
66
+	if (parent) {
67
+		[_presenter applyOptionsOnWillMoveToParentViewController:self.options];
68
+	}
69
+}
70
+
71
+- (void)mergeOptions:(RNNNavigationOptions *)options {
72
+	[_presenter mergeOptions:options];
73
+	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
74
+	
75
+	[self initCustomViews];
76
+}
77
+
62 78
 -(void)viewWillAppear:(BOOL)animated{
63 79
 	[super viewWillAppear:animated];
64 80
 	_isBeingPresented = YES;
65
-	[_presenter present:self.options onViewControllerWillAppear:self];
66
-	[self initReactCustomViews];
81
+	
82
+	[_presenter applyOptions:self.options];
83
+	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
84
+	
85
+	[self initCustomViews];
86
+}
87
+
88
+- (RNNNavigationOptions *)resolveOptions {
89
+	return self.options;
67 90
 }
68 91
 
69 92
 -(void)viewDidAppear:(BOOL)animated {
@@ -76,22 +99,11 @@
76 99
 	_isBeingPresented = NO;
77 100
 }
78 101
 
79
--(void)viewDidDisappear:(BOOL)animated {
102
+- (void)viewDidDisappear:(BOOL)animated {
80 103
 	[super viewDidDisappear:animated];
81 104
 	[self.eventEmitter sendComponentDidDisappear:self.layoutInfo.componentId componentName:self.layoutInfo.name];
82 105
 }
83 106
 
84
-- (void)willMoveToParentViewController:(UIViewController *)parent {
85
-	[_presenter present:self.options onViewControllerDidLoad:self];
86
-}
87
-
88
-- (void)mergeAndPresentOptions:(RNNNavigationOptions *)newOptions {
89
-	[self.options mergeOptions:newOptions overrideOptions:YES];
90
-	[_presenter present:self.options onViewControllerWillAppear:self];
91
-	
92
-	[self initReactCustomViews];
93
-}
94
-
95 107
 - (void)reactViewReady {
96 108
 	if (_reactViewReadyBlock) {
97 109
 		_reactViewReadyBlock();
@@ -110,7 +122,7 @@
110 122
 	}
111 123
 }
112 124
 
113
-- (UIViewController *)getLeafViewController {
125
+- (UIViewController *)getCurrentChild {
114 126
 	return self;
115 127
 }
116 128
 
@@ -132,19 +144,31 @@
132 144
 	[self.eventEmitter sendOnSearchBarCancelPressed:self.layoutInfo.componentId];
133 145
 }
134 146
 
135
-- (void)initReactCustomViews {
147
+- (void)initCustomViews {
136 148
 	[self setCustomNavigationTitleView];
137 149
 	[self setCustomNavigationBarView];
138 150
 	[self setCustomNavigationComponentBackground];
151
+	
152
+	if (!_customTitleView) {
153
+		[self setTitleViewWithSubtitle];
154
+	}
155
+}
156
+
157
+- (void)setTitleViewWithSubtitle {
158
+	if (self.options.topBar.subtitle.text.hasValue) {
159
+		RNNTitleViewHelper* titleViewHelper = [[RNNTitleViewHelper alloc] initWithTitleViewOptions:self.optionsWithDefault.topBar.title subTitleOptions:self.optionsWithDefault.topBar.subtitle viewController:self];
160
+		[titleViewHelper setup];
161
+	}
139 162
 }
140 163
 
141 164
 - (void)setCustomNavigationTitleView {
142 165
 	if (!_customTitleView && _isBeingPresented) {
143
-		if (self.options.topBar.title.component.name) {
166
+		if (self.options.topBar.title.component.name.hasValue) {
144 167
 			_customTitleView = (RNNReactView*)[_creator createRootViewFromComponentOptions:self.options.topBar.title.component];
145 168
 			_customTitleView.backgroundColor = UIColor.clearColor;
146
-			[_customTitleView setAlignment:self.options.topBar.title.component.alignment];
147
-			BOOL isCenter = [self.options.topBar.title.component.alignment isEqualToString:@"center"];
169
+			NSString* alignment = [self.options.topBar.title.component.alignment getWithDefaultValue:@""];
170
+			[_customTitleView setAlignment:alignment];
171
+			BOOL isCenter = [alignment isEqualToString:@"center"];
148 172
 			__weak RNNReactView *weakTitleView = _customTitleView;
149 173
 			CGRect frame = self.navigationController.navigationBar.bounds;
150 174
 			[_customTitleView setFrame:frame];
@@ -168,7 +192,7 @@
168 192
 
169 193
 - (void)setCustomNavigationBarView {
170 194
 	if (!_customTopBar) {
171
-		if (self.options.topBar.component.name) {
195
+		if (self.options.topBar.component.name.hasValue) {
172 196
 			RCTRootView *reactView = (RCTRootView*)[_creator createRootViewFromComponentOptions:self.options.topBar.component];
173 197
 			
174 198
 			_customTopBar = [[RNNCustomTitleView alloc] initWithFrame:self.navigationController.navigationBar.bounds subView:reactView alignment:@"fill"];
@@ -188,7 +212,7 @@
188 212
 
189 213
 - (void)setCustomNavigationComponentBackground {
190 214
 	if (!_customTopBarBackground) {
191
-		if (self.options.topBar.background.component.name) {
215
+		if (self.options.topBar.background.component.name.hasValue) {
192 216
 			RCTRootView *reactView = (RCTRootView*)[_creator createRootViewFromComponentOptions:self.options.topBar.background.component];
193 217
 			
194 218
 			_customTopBarBackground = [[RNNCustomTitleView alloc] initWithFrame:self.navigationController.navigationBar.bounds subView:reactView alignment:@"fill"];
@@ -205,8 +229,12 @@
205 229
 	}
206 230
 }
207 231
 
232
+- (RNNNavigationOptions *)optionsWithDefault {
233
+	return (RNNNavigationOptions *)[[self.options copy] withDefault:_presenter.defaultOptions];
234
+}
235
+
208 236
 -(BOOL)isCustomTransitioned {
209
-	return self.options.customTransition.animations != nil;
237
+	return self.optionsWithDefault.customTransition.animations != nil;
210 238
 }
211 239
 
212 240
 - (BOOL)isExternalViewController {
@@ -214,9 +242,9 @@
214 242
 }
215 243
 
216 244
 - (BOOL)prefersStatusBarHidden {
217
-	if (self.options.statusBar.visible) {
218
-		return ![self.options.statusBar.visible boolValue];
219
-	} else if ([self.options.statusBar.hideWithTopBar boolValue]) {
245
+	if (self.optionsWithDefault.statusBar.visible.hasValue) {
246
+		return ![self.optionsWithDefault.statusBar.visible get];
247
+	} else if ([self.optionsWithDefault.statusBar.hideWithTopBar getWithDefaultValue:NO]) {
220 248
 		return self.navigationController.isNavigationBarHidden;
221 249
 	}
222 250
 	
@@ -224,7 +252,7 @@
224 252
 }
225 253
 
226 254
 - (UIStatusBarStyle)preferredStatusBarStyle {
227
-	if (self.options.statusBar.style && [self.options.statusBar.style isEqualToString:@"light"]) {
255
+	if ([[self.optionsWithDefault.statusBar.style getWithDefaultValue:@"default"] isEqualToString:@"light"]) {
228 256
 		return UIStatusBarStyleLightContent;
229 257
 	} else {
230 258
 		return UIStatusBarStyleDefault;
@@ -232,20 +260,20 @@
232 260
 }
233 261
 
234 262
 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
235
-	return self.options.layout.supportedOrientations;
263
+	return self.optionsWithDefault.layout.supportedOrientations;
236 264
 }
237 265
 
238 266
 - (BOOL)hidesBottomBarWhenPushed
239 267
 {
240
-	if (self.options.bottomTabs && self.options.bottomTabs.visible) {
241
-		return ![self.options.bottomTabs.visible boolValue];
268
+	if (self.optionsWithDefault.bottomTabs.visible.hasValue) {
269
+		return !self.optionsWithDefault.bottomTabs.visible.get;
242 270
 	}
243 271
 	return NO;
244 272
 }
245 273
 
246 274
 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
247 275
 	RNNRootViewController* vc =  (RNNRootViewController*)viewController;
248
-	if (![vc.options.topBar.backButton.transition isEqualToString:@"custom"]){
276
+	if (![[vc.optionsWithDefault.topBar.backButton.transition getWithDefaultValue:@""] isEqualToString:@"custom"]){
249 277
 		navigationController.delegate = nil;
250 278
 	}
251 279
 }
@@ -256,10 +284,10 @@
256 284
 												 toViewController:(UIViewController*)toVC {
257 285
 	if (self.animator) {
258 286
 		return self.animator;
259
-	} else if (operation == UINavigationControllerOperationPush && self.options.animations.push.hasCustomAnimation) {
260
-		return [[RNNPushAnimation alloc] initWithScreenTransition:self.options.animations.push];
261
-	} else if (operation == UINavigationControllerOperationPop && self.options.animations.pop.hasCustomAnimation) {
262
-		return [[RNNPushAnimation alloc] initWithScreenTransition:self.options.animations.pop];
287
+	} else if (operation == UINavigationControllerOperationPush && self.optionsWithDefault.animations.push.hasCustomAnimation) {
288
+		return [[RNNPushAnimation alloc] initWithScreenTransition:self.optionsWithDefault.animations.push];
289
+	} else if (operation == UINavigationControllerOperationPop && self.optionsWithDefault.animations.pop.hasCustomAnimation) {
290
+		return [[RNNPushAnimation alloc] initWithScreenTransition:self.optionsWithDefault.animations.pop];
263 291
 	} else {
264 292
 		return nil;
265 293
 	}
@@ -268,11 +296,11 @@
268 296
 }
269 297
 
270 298
 - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
271
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.options.animations.showModal isDismiss:NO];
299
+	return [[RNNModalAnimation alloc] initWithScreenTransition:self.optionsWithDefault.animations.showModal isDismiss:NO];
272 300
 }
273 301
 
274 302
 - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
275
-	return [[RNNModalAnimation alloc] initWithScreenTransition:self.options.animations.dismissModal isDismiss:YES];
303
+	return [[RNNModalAnimation alloc] initWithScreenTransition:self.optionsWithDefault.animations.dismissModal isDismiss:YES];
276 304
 }
277 305
 
278 306
 - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{

+ 2
- 2
lib/ios/RNNSideMenuChildVC.h View File

@@ -14,9 +14,9 @@ typedef NS_ENUM(NSInteger, RNNSideMenuChildType) {
14 14
 @property (readonly) UIViewController<RNNParentProtocol> *child;
15 15
 
16 16
 @property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
17
-@property (nonatomic, retain) RNNBasePresenter* presenter;
17
+@property (nonatomic, retain) RNNViewControllerPresenter* presenter;
18 18
 @property (nonatomic, strong) RNNNavigationOptions* options;
19 19
 
20
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNBasePresenter *)presenter type:(RNNSideMenuChildType)type;
20
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNViewControllerPresenter *)presenter type:(RNNSideMenuChildType)type;
21 21
 
22 22
 @end

+ 30
- 13
lib/ios/RNNSideMenuChildVC.m View File

@@ -9,7 +9,7 @@
9 9
 
10 10
 @implementation RNNSideMenuChildVC
11 11
 
12
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNBasePresenter *)presenter type:(RNNSideMenuChildType)type {
12
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNViewControllerPresenter *)presenter type:(RNNSideMenuChildType)type {
13 13
 	self = [self initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options presenter:presenter];
14 14
 	
15 15
 	self.type = type;
@@ -17,21 +17,42 @@
17 17
 	return self;
18 18
 }
19 19
 
20
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNBasePresenter *)presenter {
20
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNViewControllerPresenter *)presenter {
21 21
 	self = [super init];
22 22
 	
23
+	self.child = childViewControllers[0];
24
+	
23 25
 	self.presenter = presenter;
26
+	[self.presenter bindViewController:self];
27
+	
28
+	
24 29
 	self.options = options;
25 30
 	self.layoutInfo = layoutInfo;
26 31
 	
27
-	[self bindChildViewControllers:childViewControllers];
28
-	
32
+	[self bindChildViewController:self.child];
33
+
29 34
 	return self;
30 35
 }
31 36
 
32
-- (void)bindChildViewControllers:(NSArray<UIViewController<RNNParentProtocol> *> *)viewControllers {
33
-	UIViewController<RNNParentProtocol>* child = viewControllers[0];
34
-	
37
+- (void)onChildWillAppear {
38
+	[_presenter applyOptions:self.resolveOptions];
39
+	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
40
+}
41
+
42
+- (RNNNavigationOptions *)resolveOptions {
43
+	return (RNNNavigationOptions *)[self.getCurrentChild.resolveOptions.copy mergeOptions:self.options];
44
+}
45
+
46
+- (void)mergeOptions:(RNNNavigationOptions *)options {
47
+	[_presenter mergeOptions:options];
48
+	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
49
+}
50
+
51
+- (UITabBarItem *)tabBarItem {
52
+	return super.tabBarItem ? super.tabBarItem : self.child.tabBarItem;
53
+}
54
+
55
+- (void)bindChildViewController:(UIViewController<RNNParentProtocol>*)child {
35 56
 	self.child = child;
36 57
 	[self addChildViewController:self.child];
37 58
 	[self.child.view setFrame:self.view.bounds];
@@ -39,12 +60,8 @@
39 60
 	[self.view bringSubviewToFront:self.child.view];
40 61
 }
41 62
 
42
-- (UIViewController *)getLeafViewController {
43
-	return [self.child getLeafViewController];
44
-}
45
-
46
-- (void)willMoveToParentViewController:(UIViewController *)parent {
47
-	[_presenter present:self.options onViewControllerDidLoad:self];
63
+- (UIViewController *)getCurrentChild {
64
+	return [self.child getCurrentChild];
48 65
 }
49 66
 
50 67
 - (UIStatusBarStyle)preferredStatusBarStyle {

+ 5
- 13
lib/ios/RNNSideMenuController.h View File

@@ -1,28 +1,20 @@
1
-//
2
-//  RNNSideMenuController.h
3
-//  ReactNativeNavigation
4
-//
5
-//  Created by Ran Greenberg on 09/02/2017.
6
-//  Copyright © 2017 Wix. All rights reserved.
7
-//
8
-
9 1
 #import <UIKit/UIKit.h>
10 2
 #import "RNNSideMenuChildVC.h"
11 3
 #import "MMDrawerController.h"
12 4
 #import "RNNParentProtocol.h"
13 5
 
14
-@interface RNNSideMenuController : UIViewController <RNNParentProtocol>
6
+@interface RNNSideMenuController : MMDrawerController <RNNParentProtocol>
15 7
 
16 8
 @property (readonly) RNNSideMenuChildVC *center;
17 9
 @property (readonly) RNNSideMenuChildVC *left;
18 10
 @property (readonly) RNNSideMenuChildVC *right;
19
-@property (readonly) MMDrawerController *sideMenu;
20 11
 
21 12
 @property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
22
-@property (nonatomic, retain) RNNBasePresenter* presenter;
13
+@property (nonatomic, retain) RNNViewControllerPresenter* presenter;
23 14
 @property (nonatomic, strong) RNNNavigationOptions* options;
24 15
 
25
--(void)showSideMenu:(MMDrawerSide)side animated:(BOOL)animated;
26
--(void)hideSideMenu:(MMDrawerSide)side animated:(BOOL)animated;
16
+- (void)side:(MMDrawerSide)side enabled:(BOOL)enabled;
17
+- (void)side:(MMDrawerSide)side visible:(BOOL)visible;
18
+- (void)side:(MMDrawerSide)side width:(double)width;
27 19
 
28 20
 @end

+ 85
- 32
lib/ios/RNNSideMenuController.m View File

@@ -1,34 +1,31 @@
1
-//
2
-//  RNNSideMenuController.m
3
-//  ReactNativeNavigation
4
-//
5
-//  Created by Ran Greenberg on 09/02/2017.
6
-//  Copyright © 2017 Wix. All rights reserved.
7
-//
8
-
9 1
 #import "RNNSideMenuController.h"
10 2
 #import "RNNSideMenuChildVC.h"
11 3
 #import "MMDrawerController.h"
4
+#import "MMDrawerVisualState.h"
12 5
 
13 6
 @interface RNNSideMenuController ()
14 7
 
15 8
 @property (readwrite) RNNSideMenuChildVC *center;
16 9
 @property (readwrite) RNNSideMenuChildVC *left;
17 10
 @property (readwrite) RNNSideMenuChildVC *right;
18
-@property (readwrite) MMDrawerController *sideMenu;
19 11
 
20 12
 @end
21 13
 
22 14
 @implementation RNNSideMenuController
23 15
 
24
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNBasePresenter *)presenter {
25
-	self = [super init];
16
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options presenter:(RNNViewControllerPresenter *)presenter {
17
+	[self setControllers:childViewControllers];
18
+	self = [super initWithCenterViewController:self.center leftDrawerViewController:self.left rightDrawerViewController:self.right];
26 19
 	
27 20
 	self.presenter = presenter;
21
+	[self.presenter bindViewController:self];
22
+	
28 23
 	self.options = options;
24
+	
29 25
 	self.layoutInfo = layoutInfo;
30 26
 	
31
-	[self bindChildViewControllers:childViewControllers];
27
+	self.openDrawerGestureModeMask = MMOpenDrawerGestureModeAll;
28
+	self.closeDrawerGestureModeMask = MMCloseDrawerGestureModeAll;
32 29
 	
33 30
 	// Fixes #3697
34 31
 	[self setExtendedLayoutIncludesOpaqueBars:YES];
@@ -37,26 +34,86 @@
37 34
 	return self;
38 35
 }
39 36
 
40
-- (void)bindChildViewControllers:(NSArray<UIViewController<RNNLayoutProtocol> *> *)viewControllers {
41
-	[self setControllers:viewControllers];
42
-	
43
-	self.sideMenu = [[MMDrawerController alloc] initWithCenterViewController:self.center leftDrawerViewController:self.left rightDrawerViewController:self.right];
44
-	
45
-	self.sideMenu.openDrawerGestureModeMask = MMOpenDrawerGestureModeAll;
46
-	self.sideMenu.closeDrawerGestureModeMask = MMCloseDrawerGestureModeAll;
37
+- (void)willMoveToParentViewController:(UIViewController *)parent {
38
+	if (parent) {
39
+		[_presenter applyOptionsOnWillMoveToParentViewController:self.options];
40
+	}
41
+}
42
+
43
+- (void)viewWillAppear:(BOOL)animated {
44
+	[super viewWillAppear:animated];
45
+	[_presenter applyOptions:self.options];
46
+}
47
+
48
+- (UITabBarItem *)tabBarItem {
49
+	return super.tabBarItem ? super.tabBarItem : self.center.tabBarItem;
50
+}
51
+
52
+- (void)onChildWillAppear {
53
+	[_presenter applyOptions:self.resolveOptions];
54
+	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
55
+}
56
+
57
+- (RNNNavigationOptions *)resolveOptions {
58
+	return (RNNNavigationOptions *)[self.getCurrentChild.resolveOptions.copy mergeOptions:self.options];
59
+}
60
+
61
+- (void)mergeOptions:(RNNNavigationOptions *)options {
62
+	[_presenter mergeOptions:options];
63
+	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
64
+}
65
+
66
+- (void)setAnimationType:(NSString *)animationType {
67
+	MMDrawerControllerDrawerVisualStateBlock animationTypeStateBlock = nil;
68
+	if ([animationType isEqualToString:@"door"]) animationTypeStateBlock = [MMDrawerVisualState swingingDoorVisualStateBlock];
69
+	else if ([animationType isEqualToString:@"parallax"]) animationTypeStateBlock = [MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:2.0];
70
+	else if ([animationType isEqualToString:@"slide"]) animationTypeStateBlock = [MMDrawerVisualState slideVisualStateBlock];
71
+	else if ([animationType isEqualToString:@"slide-and-scale"]) animationTypeStateBlock = [MMDrawerVisualState slideAndScaleVisualStateBlock];
47 72
 	
48
-	[self addChildViewController:self.sideMenu];
49
-	[self.sideMenu.view setFrame:self.view.bounds];
50
-	[self.view addSubview:self.sideMenu.view];
51
-	[self.view bringSubviewToFront:self.sideMenu.view];
73
+	if (animationTypeStateBlock) {
74
+		[self setDrawerVisualStateBlock:animationTypeStateBlock];
75
+	}
76
+}
77
+
78
+- (void)side:(MMDrawerSide)side width:(double)width {
79
+	switch (side) {
80
+		case MMDrawerSideRight:
81
+			self.maximumRightDrawerWidth = width;
82
+			break;
83
+		case MMDrawerSideLeft:
84
+			self.maximumLeftDrawerWidth = width;
85
+		default:
86
+			break;
87
+	}
88
+}
89
+
90
+- (void)side:(MMDrawerSide)side visible:(BOOL)visible {
91
+	if (visible) {
92
+		[self showSideMenu:side animated:YES];
93
+	} else {
94
+		[self hideSideMenu:side animated:YES];
95
+	}
52 96
 }
53 97
 
54 98
 -(void)showSideMenu:(MMDrawerSide)side animated:(BOOL)animated {
55
-	[self.sideMenu openDrawerSide:side animated:animated completion:nil];
99
+	[self openDrawerSide:side animated:animated completion:nil];
56 100
 }
57 101
 
58 102
 -(void)hideSideMenu:(MMDrawerSide)side animated:(BOOL)animated {
59
-	[self.sideMenu closeDrawerAnimated:animated completion:nil];
103
+	[self closeDrawerAnimated:animated completion:nil];
104
+}
105
+
106
+- (void)side:(MMDrawerSide)side enabled:(BOOL)enabled {
107
+	switch (side) {
108
+		case MMDrawerSideRight:
109
+			self.rightSideEnabled = enabled;
110
+			break;
111
+		case MMDrawerSideLeft:
112
+			self.leftSideEnabled = enabled;
113
+		default:
114
+			break;
115
+	}
116
+	self.openDrawerGestureModeMask = enabled ? MMOpenDrawerGestureModeAll : MMOpenDrawerGestureModeNone;
60 117
 }
61 118
 
62 119
 -(void)setControllers:(NSArray*)controllers {
@@ -87,7 +144,7 @@
87 144
 }
88 145
 
89 146
 - (UIViewController *)openedViewController {
90
-	switch (self.sideMenu.openSide) {
147
+	switch (self.openSide) {
91 148
 		case MMDrawerSideNone:
92 149
 			return self.center;
93 150
 		case MMDrawerSideLeft:
@@ -100,12 +157,8 @@
100 157
 	}
101 158
 }
102 159
 
103
-- (UIViewController<RNNLayoutProtocol> *)getLeafViewController {
104
-	return [self.center getLeafViewController];
105
-}
106
-
107
-- (void)willMoveToParentViewController:(UIViewController *)parent {
108
-	[_presenter present:self.options onViewControllerDidLoad:self];
160
+- (UIViewController<RNNLayoutProtocol> *)getCurrentChild {
161
+	return [self.center getCurrentChild];
109 162
 }
110 163
 
111 164
 @end

+ 0
- 0
lib/ios/RNNSideMenuOptions.h View File


Some files were not shown because too many files changed in this diff