Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Viewport] Add utility to get viewport dimensions #418

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions Libraries/Utilities/Viewport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Viewport
* @flow
*/
'use strict';

var NativeModules = require('NativeModules');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTDimensionManager = NativeModules.DimensionManager;

var logError = require('logError');

var DEVICE_DIMENSIONS_EVENT = 'dimensionsDidChange';

/**
* ViewPortDimensions class gives access to the viewport's height and width.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Viewport instead of ViewPortDimensions

*
* This could be used if someone wanted an image which stretched the width of
* the device.
*
* Note: The values returned here are all ready in terms of the pixel ratio of
* the device. For example, the iPhone 6 renders 750x1334 pixels. However, it has
* a pixel ratio of two. Therefore the return values of these functions will
* all ready be modified by the pixel ratio. In the iPhone 6's case this means
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already instead of all ready

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change, but 'all ready' is a real thing! 'already' is just a bastardization! haha

* that the resolution that gets returned will be 375x667.
*/
var Viewport = {};

if (RCTDimensionManager) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this check... this library should be always present since it's part of the core, and it doesn't call any method at initialization time anyway.

var _dimensionSubscriptions = {};

Viewport.addEventListener = function(
eventName: ChangeEventName,
handler: Function
): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use the eventName right now, but it's nice to add an invariant(eventName === 'dimensionsDidChange', ...) so if we need to use it, we are sure that people are listening to the right event.

_dimensionSubscriptions[handler] = RCTDeviceEventEmitter.addListener(
DEVICE_DIMENSIONS_EVENT,
handler
);
};

Viewport.removeEventListener = function(
eventName: ChangeEventName,
handler: Function
): void {
if (!_dimensionSubscriptions[handler]) {
return;
}
_dimensionSubscriptions[handler].remove();
_dimensionSubscriptions[handler] = null;
};

Viewport.getDimensions = function(
handler: Function
) {
RCTDimensionManager.getCurrentDimensions(handler, logError);
}
}

module.exports = Viewport;
1 change: 1 addition & 0 deletions Libraries/react-native/react-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
StatusBarIOS: require('StatusBarIOS'),
StyleSheet: require('StyleSheet'),
VibrationIOS: require('VibrationIOS'),
Viewport: require('Viewport'),

// Plugins
DeviceEventEmitter: require('RCTDeviceEventEmitter'),
Expand Down
14 changes: 14 additions & 0 deletions React/Modules/RCTDimensionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import "RCTBridgeModule.h"

@interface RCTDimensionManager : NSObject<RCTBridgeModule>

@end
84 changes: 84 additions & 0 deletions React/Modules/RCTDimensionManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please indent it with 2 spaces? 😅

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Derp...will do.

* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import "RCTDimensionManager.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTUtils.h"

static NSDictionary *RCTCurrentDimensions()
{
static NSDictionary *dimensions;

CGSize frameSize = [UIScreen mainScreen].applicationFrame.size;
if ((NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
&& UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
frameSize = CGSizeMake(frameSize.height, frameSize.width);
}

dimensions = @{
@"width": [NSNumber numberWithFloat:frameSize.width],
@"height": [NSNumber numberWithFloat:frameSize.height]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@{
  @"width": @(frameSize.width),
  @"height": @(frameSize.height),
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it like that at first but it wouldn't compile. frameSize.width/height are floats and apparently you can't put floats in an NSDictionary. So I had to convert them to NSNumbers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pjjanak The syntax @(someFloatValue) is a shorthand in Objective-C for [NSNumber numberWithFloat:someFloatValue].

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, gotcha. I'll switch that out then.

};

return dimensions;
}


@implementation RCTDimensionManager
{
NSDictionary *_lastKnownDimensions;
}

@synthesize bridge = _bridge;

#pragma mark - Lifecycle

- (instancetype)init
{
if ((self = [super init])) {
_lastKnownDimensions = RCTCurrentDimensions();

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChangeNotification:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}

return self;
}

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Notification methods

- (void)deviceOrientationDidChangeNotification:(NSNotification*)note
{
_lastKnownDimensions = RCTCurrentDimensions();
[_bridge.eventDispatcher sendDeviceEventWithName:@"dimensionsDidChange" body:_lastKnownDimensions];
}

#pragma mark - Public API
/**
* Get the current dimensions of the viewport
*/
- (void)getCurrentDimensions:(RCTResponseSenderBlock)callback
error:(__unused RCTResponseSenderBlock)error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for this error callback?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was just basing it off of AppState's handlers. If I can remove it without issue I will.

{
RCT_EXPORT();
_lastKnownDimensions = RCTCurrentDimensions();

callback(@[_lastKnownDimensions]);
}


@end
6 changes: 6 additions & 0 deletions React/React.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
EBA277681ACB4502008D277F /* RCTDimensionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EBA277671ACB4502008D277F /* RCTDimensionManager.m */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -190,6 +191,8 @@
83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchHandler.m; sourceTree = "<group>"; };
83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = "<group>"; };
83CBBACB1A6023D300E9B192 /* RCTConvert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = "<group>"; };
EBA277661ACB44EC008D277F /* RCTDimensionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDimensionManager.h; sourceTree = "<group>"; };
EBA277671ACB4502008D277F /* RCTDimensionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDimensionManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -242,6 +245,8 @@
13B07FEE1A69327A00A75B9A /* RCTTiming.m */,
13E067481A70F434002CDEE1 /* RCTUIManager.h */,
13E067491A70F434002CDEE1 /* RCTUIManager.m */,
EBA277661ACB44EC008D277F /* RCTDimensionManager.h */,
EBA277671ACB4502008D277F /* RCTDimensionManager.m */,
);
path = Modules;
sourceTree = "<group>";
Expand Down Expand Up @@ -503,6 +508,7 @@
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */,
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
EBA277681ACB4502008D277F /* RCTDimensionManager.m in Sources */,
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */,
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */,
13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */,
Expand Down
1 change: 1 addition & 0 deletions website/server/extractDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ var apis = [
'../Libraries/Components/StatusBar/StatusBarIOS.ios.js',
'../Libraries/StyleSheet/StyleSheet.js',
'../Libraries/Vibration/VibrationIOS.ios.js',
'../Libraries/Utilities/ViewPortDimensions.js',
];

var styles = [
Expand Down