Browse Source

Use autolayout constraints to set size of custom bar button item (#4732)

This fixes an issue where the frame for the custom view can be set to the incorrect y-offset upon setting the custom frame.

In iOS 11, this behavior changed, as UIBarButtonItem went from being using springs-and-struts for sizing, to using a UIStackView, and thus using Autolayout.

This lead to the superview of having a frame of (0, 22, 0, 0) at the first layout pass.

By moving to using NSLayoutConstaints, we can now properly size our custom view.

See also: https://gist.github.com/niw/569b49648f
See also: https://stackoverflow.com/questions/10988918/change-width-of-a-uibarbuttonitem-in-a-uinavigationbar
Eli Perkins 5 years ago
parent
commit
362606b82e
1 changed files with 28 additions and 5 deletions
  1. 28
    5
      lib/ios/RNNUIBarButtonItem.m

+ 28
- 5
lib/ios/RNNUIBarButtonItem.m View File

@@ -3,6 +3,13 @@
3 3
 #import "RNNUIBarButtonItem.h"
4 4
 #import "RCTConvert+UIBarButtonSystemItem.h"
5 5
 
6
+@interface RNNUIBarButtonItem ()
7
+
8
+@property (nonatomic, strong) NSLayoutConstraint *widthConstraint;
9
+@property (nonatomic, strong) NSLayoutConstraint *heightConstraint;
10
+
11
+@end
12
+
6 13
 @implementation RNNUIBarButtonItem
7 14
 
8 15
 -(instancetype)init:(NSString*)buttonId withIcon:(UIImage*)iconImage {
@@ -26,11 +33,26 @@
26 33
 	reactView.sizeFlexibility = RCTRootViewSizeFlexibilityWidthAndHeight;
27 34
 	reactView.delegate = self;
28 35
 	reactView.backgroundColor = [UIColor clearColor];
36
+	self.widthConstraint = [NSLayoutConstraint constraintWithItem:reactView
37
+														attribute:NSLayoutAttributeWidth
38
+														relatedBy:NSLayoutRelationEqual
39
+														   toItem:nil
40
+														attribute:NSLayoutAttributeNotAnAttribute
41
+													   multiplier:1.0
42
+														 constant:1.0];
43
+	self.heightConstraint = [NSLayoutConstraint constraintWithItem:reactView
44
+														 attribute:NSLayoutAttributeHeight
45
+														 relatedBy:NSLayoutRelationEqual
46
+														   	toItem:nil
47
+														 attribute:NSLayoutAttributeNotAnAttribute
48
+													   	multiplier:1.0
49
+														  constant:1.0];
50
+	[NSLayoutConstraint activateConstraints:@[self.widthConstraint, self.heightConstraint]];
29 51
 	self.buttonId = buttonId;
30 52
 	return self;
31 53
 }
32
-
33
--(instancetype)init:(NSString*)buttonId withSystemItem:(NSString *)systemItemName {
54
+	
55
+- (instancetype)init:(NSString*)buttonId withSystemItem:(NSString *)systemItemName {
34 56
 	UIBarButtonSystemItem systemItem = [RCTConvert UIBarButtonSystemItem:systemItemName];
35 57
 	self = [super initWithBarButtonSystemItem:systemItem target:nil action:nil];
36 58
 	self.buttonId = buttonId;
@@ -38,9 +60,10 @@
38 60
 }
39 61
 
40 62
 - (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {
41
-	CGSize size = rootView.intrinsicContentSize;
42
-	rootView.frame = CGRectMake(0, 0, size.width, size.height);
43
-	self.width = size.width;
63
+	self.widthConstraint.constant = rootView.intrinsicContentSize.width;
64
+	self.heightConstraint.constant = rootView.intrinsicContentSize.height;
65
+	[rootView setNeedsUpdateConstraints];
66
+	[rootView updateConstraintsIfNeeded];
44 67
 }
45 68
 
46 69
 - (void)onButtonPressed {