@@ -63,10 +63,14 @@ + (void)load
6363 Method original, swizzle;
6464
6565 original = class_getInstanceMethod (self, @selector (pushViewController:animated: ));
66-
6766 swizzle = class_getInstanceMethod (self, @selector (sizzled_pushViewController:animated: ));
6867
6968 method_exchangeImplementations (original, swizzle);
69+
70+ original = class_getInstanceMethod (self, @selector (setViewControllers:animated: ));
71+ swizzle = class_getInstanceMethod (self, @selector (sizzled_setViewControllers:animated: ));
72+
73+ method_exchangeImplementations (original, swizzle);
7074}
7175
7276- (BOOL )isEmbedInPopover
@@ -88,23 +92,99 @@ - (void)setEmbedInPopover:(BOOL)value
8892 objc_setAssociatedObject (self, UINavigationControllerEmbedInPopoverTagKey, [NSNumber numberWithBool: value], OBJC_ASSOCIATION_RETAIN_NONATOMIC );
8993}
9094
91- - (void )sizzled_pushViewController : (UIViewController *)viewController animated : (BOOL )animated
95+ - (void )sizzled_pushViewController : (UIViewController *)aViewController animated : (BOOL )aAnimated
96+ {
97+ if (self.isEmbedInPopover )
98+ {
99+ #ifdef WY_BASE_SDK_7_ENABLED
100+ if ([aViewController respondsToSelector: @selector (setEdgesForExtendedLayout: )])
101+ {
102+ aViewController.edgesForExtendedLayout = UIRectEdgeNone;
103+ }
104+ #endif
105+ }
106+
107+ [self sizzled_pushViewController: aViewController animated: aAnimated];
108+ }
109+
110+ - (void )sizzled_setViewControllers : (NSArray *)aViewControllers animated : (BOOL )aAnimated
92111{
93112 if (self.isEmbedInPopover )
94113 {
95114#ifdef WY_BASE_SDK_7_ENABLED
96- if ([viewController respondsToSelector: @selector ( setEdgesForExtendedLayout: )] )
115+ if (aViewControllers && [aViewControllers count ] > 0 )
97116 {
98- viewController.edgesForExtendedLayout = UIRectEdgeNone;
117+ for (UIViewController *viewController in aViewControllers) {
118+ if ([viewController respondsToSelector: @selector (setEdgesForExtendedLayout: )])
119+ {
120+ viewController.edgesForExtendedLayout = UIRectEdgeNone;
121+ }
122+ }
99123 }
100124#endif
101125 }
102126
103- [self sizzled_pushViewController: viewController animated: animated ];
127+ [self sizzled_setViewControllers: aViewControllers animated: aAnimated ];
104128}
105129
106130@end
107131
132+ // //////////////////////////////////////////////////////////////////////////////////////////////////////
133+
134+ @interface UIViewController (WYPopover)
135+ @end
136+
137+ @implementation UIViewController (WYPopover)
138+
139+ + (void )load
140+ {
141+ Method original, swizzle;
142+
143+ #pragma clang diagnostic push
144+ #pragma GCC diagnostic ignored "-Wdeprecated"
145+ original = class_getInstanceMethod (self, @selector (setContentSizeForViewInPopover: ));
146+ swizzle = class_getInstanceMethod (self, @selector (sizzled_setContentSizeForViewInPopover: ));
147+ method_exchangeImplementations (original, swizzle);
148+ #pragma clang diagnostic pop
149+
150+ #ifdef WY_BASE_SDK_7_ENABLED
151+ original = class_getInstanceMethod (self, @selector (setPreferredContentSize: ));
152+ swizzle = class_getInstanceMethod (self, @selector (sizzled_setPreferredContentSize: ));
153+
154+ if (original != NULL ) {
155+ method_exchangeImplementations (original, swizzle);
156+ }
157+ #endif
158+ }
159+
160+ - (void )sizzled_setContentSizeForViewInPopover : (CGSize)aSize
161+ {
162+ [self sizzled_setContentSizeForViewInPopover: aSize];
163+
164+ if ([self isKindOfClass: [UINavigationController class ]] == NO && self.navigationController != nil )
165+ {
166+ #pragma clang diagnostic push
167+ #pragma GCC diagnostic ignored "-Wdeprecated"
168+ [self .navigationController setContentSizeForViewInPopover: aSize];
169+ #pragma clang diagnostic pop
170+ }
171+ }
172+
173+ - (void )sizzled_setPreferredContentSize : (CGSize)aSize
174+ {
175+ [self sizzled_setPreferredContentSize: aSize];
176+
177+ if ([self isKindOfClass: [UINavigationController class ]] == NO && self.navigationController != nil )
178+ {
179+ #ifdef WY_BASE_SDK_7_ENABLED
180+ if ([self respondsToSelector: @selector (setPreferredContentSize: )]) {
181+ [self .navigationController setPreferredContentSize: aSize];
182+ }
183+ #endif
184+ }
185+ }
186+
187+ @end
108188
109189// //////////////////////////////////////////////////////////////////////////////////////////////////////
110190
@@ -1342,7 +1422,7 @@ @interface WYPopoverController () <WYPopoverOverlayViewDelegate>
13421422 WYPopoverAnimationOptions options;
13431423}
13441424
1345- @property (nonatomic , assign , readonly ) CGSize contentSizeForViewInPopover;
1425+ // @property (nonatomic, assign, readonly) CGSize contentSizeForViewInPopover;
13461426
13471427- (void )dismissPopoverAnimated : (BOOL )animated
13481428 options : (WYPopoverAnimationOptions)options
@@ -1406,75 +1486,76 @@ - (CGSize)popoverContentSize
14061486{
14071487 CGSize result = CGSizeZero;
14081488
1409- #ifdef WY_BASE_SDK_7_ENABLED
1410- if ([viewController respondsToSelector: @selector (preferredContentSize )])
1411- {
1412- result = [viewController preferredContentSize ];
1413- }
1414- else
1415- #endif
1489+ UIViewController *topViewController = viewController;
1490+
1491+ if ([viewController isKindOfClass: [UINavigationController class ]] == YES )
14161492 {
1417- #pragma clang diagnostic push
1418- #pragma GCC diagnostic ignored "-Wdeprecated"
1419- result = [viewController contentSizeForViewInPopover ];
1420- #pragma clang diagnostic pop
1493+ UINavigationController *navigationController = (UINavigationController *)viewController;
1494+ topViewController = [navigationController topViewController ];
14211495 }
14221496
1423- return result;
1424- }
1425-
1426- - (void )setPopoverContentSize : (CGSize)size
1427- {
14281497#ifdef WY_BASE_SDK_7_ENABLED
1429- if ([viewController respondsToSelector: @selector (setPreferredContentSize: )])
1498+ if ([topViewController respondsToSelector: @selector (preferredContentSize )])
14301499 {
1431- [viewController setPreferredContentSize: size] ;
1500+ result = topViewController. preferredContentSize ;
14321501 }
1433- else
14341502#endif
1503+
1504+ if (CGSizeEqualToSize (result, CGSizeZero))
14351505 {
14361506#pragma clang diagnostic push
14371507#pragma GCC diagnostic ignored "-Wdeprecated"
1438- [viewController setContentSizeForViewInPopover: size] ;
1508+ result = topViewController. contentSizeForViewInPopover ;
14391509#pragma clang diagnostic pop
14401510 }
14411511
1442- [self positionPopover ];
1512+ if (CGSizeEqualToSize (result, CGSizeZero))
1513+ {
1514+ result = CGSizeMake (320 , 1100 );
1515+ }
1516+
1517+ return result;
14431518}
14441519
1445- - (CGSize)contentSizeForViewInPopover
1520+ - (void ) setPopoverContentSize : ( CGSize)size
14461521{
1447- CGSize result = CGSizeZero;
1448-
1449- UIViewController *controller = viewController;
1522+ UIViewController *topViewController = viewController;
14501523
1451- if ([controller isKindOfClass: [UINavigationController class ]])
1524+ if ([viewController isKindOfClass: [UINavigationController class ]] == YES )
14521525 {
1453- UINavigationController *navigationController = (UINavigationController *)controller;
1454-
1455- controller = [navigationController visibleViewController ];
1526+ UINavigationController *navigationController = (UINavigationController *)viewController;
1527+ topViewController = [navigationController topViewController ];
14561528 }
14571529
14581530#ifdef WY_BASE_SDK_7_ENABLED
1459- if ([controller respondsToSelector: @selector (preferredContentSize )])
1531+ if ([viewController respondsToSelector: @selector (setPreferredContentSize: )])
14601532 {
1461- result = controller.preferredContentSize ;
1533+ @try {
1534+ [viewController removeObserver: self forKeyPath: NSStringFromSelector (@selector (setPreferredContentSize ))];
1535+ }
1536+ @catch (NSException * __unused exception) {}
1537+
1538+ [topViewController setPreferredContentSize: size];
1539+
1540+ [viewController addObserver: self forKeyPath: NSStringFromSelector (@selector (preferredContentSize )) options: 0 context: nil ];
14621541 }
1542+ else
14631543#endif
1464- if (CGSizeEqualToSize (result, CGSizeZero))
14651544 {
14661545#pragma clang diagnostic push
14671546#pragma GCC diagnostic ignored "-Wdeprecated"
1468- result = controller.contentSizeForViewInPopover ;
1547+ @try {
1548+ [viewController removeObserver: self forKeyPath: NSStringFromSelector (@selector (contentSizeForViewInPopover ))];
1549+ }
1550+ @catch (NSException * __unused exception) {}
1551+
1552+ [topViewController setContentSizeForViewInPopover: size];
1553+
1554+ [viewController addObserver: self forKeyPath: NSStringFromSelector (@selector (contentSizeForViewInPopover )) options: 0 context: nil ];
14691555#pragma clang diagnostic pop
14701556 }
14711557
1472- if (CGSizeEqualToSize (result, CGSizeZero))
1473- {
1474- result = CGSizeMake (320 , 1100 );
1475- }
1476-
1477- return result;
1558+ [self positionPopover ];
14781559}
14791560
14801561- (void )presentPopoverFromRect : (CGRect)aRect
@@ -1532,7 +1613,7 @@ - (void)presentPopoverFromRect:(CGRect)aRect
15321613 animated = aAnimated;
15331614 options = aOptions;
15341615
1535- CGSize contentViewSize = self.contentSizeForViewInPopover ;
1616+ CGSize contentViewSize = self.popoverContentSize ;
15361617
15371618 if (overlayView == nil )
15381619 {
@@ -1603,6 +1684,15 @@ - (void)presentPopoverFromRect:(CGRect)aRect
16031684 }
16041685
16051686 strongSelf->containerView .accessibilityViewIsModal = NO ;
1687+
1688+ if ([strongSelf->viewController respondsToSelector: @selector (preferredContentSize )])
1689+ {
1690+ [strongSelf->viewController addObserver: self forKeyPath: NSStringFromSelector (@selector (preferredContentSize )) options: 0 context: nil ];
1691+ }
1692+ else
1693+ {
1694+ [strongSelf->viewController addObserver: self forKeyPath: NSStringFromSelector (@selector (contentSizeForViewInPopover )) options: 0 context: nil ];
1695+ }
16061696 }
16071697
16081698 if (completion)
@@ -1613,6 +1703,8 @@ - (void)presentPopoverFromRect:(CGRect)aRect
16131703 {
16141704 [strongSelf->delegate popoverControllerDidPresentPopover: strongSelf];
16151705 }
1706+
1707+
16161708 };
16171709
16181710#ifdef WY_BASE_SDK_7_ENABLED
@@ -1823,24 +1915,23 @@ - (CGAffineTransform)transformForArrowDirection:(WYPopoverArrowDirection)arrowDi
18231915
18241916- (void )setPopoverNavigationBarBackgroundImage
18251917{
1826- if (wantsDefaultContentAppearance == NO && [viewController isKindOfClass: [UINavigationController class ]])
1918+ if ([viewController isKindOfClass: [UINavigationController class ]] == YES )
18271919 {
18281920 UINavigationController *navigationController = (UINavigationController *)viewController;
18291921 navigationController.embedInPopover = YES ;
18301922
1831- if ([navigationController viewControllers ] && [[navigationController viewControllers ] count ] > 0 )
1832- {
18331923#ifdef WY_BASE_SDK_7_ENABLED
1834- UIViewController *firstViewController = (UIViewController *)[[navigationController viewControllers ] objectAtIndex: 0 ];
1835-
1836- if ([firstViewController respondsToSelector: @selector (setEdgesForExtendedLayout: )])
1837- {
1838- [firstViewController setEdgesForExtendedLayout: UIRectEdgeNone];
1839- }
1840- #endif
1924+ if ([navigationController respondsToSelector: @selector (setEdgesForExtendedLayout: )])
1925+ {
1926+ UIViewController *topViewController = [navigationController topViewController ];
1927+ [topViewController setEdgesForExtendedLayout: UIRectEdgeNone];
18411928 }
1929+ #endif
18421930
1843- [navigationController.navigationBar setBackgroundImage: [UIImage imageWithColor: [UIColor clearColor ]] forBarMetrics: UIBarMetricsDefault];
1931+ if (wantsDefaultContentAppearance == NO )
1932+ {
1933+ [navigationController.navigationBar setBackgroundImage: [UIImage imageWithColor: [UIColor clearColor ]] forBarMetrics: UIBarMetricsDefault];
1934+ }
18441935 }
18451936
18461937 viewController.view .clipsToBounds = YES ;
@@ -1855,7 +1946,7 @@ - (void)positionPopover
18551946{
18561947 UIInterfaceOrientation orientation = [[UIApplication sharedApplication ] statusBarOrientation ];
18571948
1858- CGSize contentViewSize = self.contentSizeForViewInPopover ;
1949+ CGSize contentViewSize = self.popoverContentSize ;
18591950 CGSize minContainerSize = WY_POPOVER_MIN_SIZE;
18601951
18611952 CGRect viewFrame;
@@ -2116,8 +2207,6 @@ - (void)positionPopover
21162207
21172208 containerFrame = CGRectIntegral (containerFrame);
21182209
2119- containerView.frame = containerFrame;
2120-
21212210 containerView.wantsDefaultContentAppearance = wantsDefaultContentAppearance;
21222211
21232212 [containerView setViewController: viewController];
@@ -2145,9 +2234,7 @@ - (void)positionPopover
21452234 containerFrame = containerView.frame ;
21462235
21472236 containerFrame.origin = WYPointRelativeToOrientation (containerOrigin, containerFrame.size , orientation);
2148-
2149-
2150-
2237+
21512238 containerView.frame = containerFrame;
21522239}
21532240
@@ -2285,6 +2372,15 @@ - (void)dismissPopoverAnimated:(BOOL)aAnimated
22852372 [viewController viewWillDisappear: aAnimated];
22862373 }
22872374
2375+ @try {
2376+ if ([viewController respondsToSelector: @selector (preferredContentSize )]) {
2377+ [viewController removeObserver: self forKeyPath: NSStringFromSelector (@selector (preferredContentSize ))];
2378+ } else {
2379+ [viewController removeObserver: self forKeyPath: NSStringFromSelector (@selector (contentSizeForViewInPopover ))];
2380+ }
2381+ }
2382+ @catch (NSException * __unused exception) {}
2383+
22882384 if (aAnimated)
22892385 {
22902386 [UIView animateWithDuration: duration animations: ^{
@@ -2315,6 +2411,20 @@ - (void)dismissPopoverAnimated:(BOOL)aAnimated
23152411 overlayView.isAccessibilityElement = NO ;
23162412}
23172413
2414+ #pragma mark KVO
2415+
2416+ - (void )observeValueForKeyPath : (NSString *)keyPath ofObject : (id )object change : (NSDictionary *)change context : (void *)context
2417+ {
2418+ if (object == viewController)
2419+ {
2420+ if ([keyPath isEqualToString: NSStringFromSelector (@selector (preferredContentSize ))]
2421+ || [keyPath isEqualToString: NSStringFromSelector (@selector (contentSizeForViewInPopover ))])
2422+ {
2423+ [self positionPopover ];
2424+ }
2425+ }
2426+ }
2427+
23182428#pragma mark WYPopoverOverlayViewDelegate
23192429
23202430- (void )popoverOverlayView : (WYPopoverOverlayView *)aOverlayView didTouchAtPoint : (CGPoint)aPoint
@@ -2708,7 +2818,6 @@ - (void)keyboardWillShow:(NSNotification *)notification
27082818 UIInterfaceOrientation orientation = [[UIApplication sharedApplication ] statusBarOrientation ];
27092819
27102820 WY_LOG (@" orientation = %@ " , WYStringFromOrientation (orientation));
2711-
27122821 WY_LOG (@" keyboardRect = %@ " , NSStringFromCGRect(keyboardRect));
27132822
27142823 [self positionPopover ];
0 commit comments