Skip to content

Commit

Permalink
iOS: Enable views to be nested within <Text>
Browse files Browse the repository at this point in the history
Summary:
Previously, only Text and Image could be nested within Text. Now, any
view can be nested within Text. One restriction of this feature is
that developers must give inline views a width and a height via
the style prop.

Previously, inline Images were supported by using iOS's built-in support
for rendering images with an NSAttributedString via NSTextAttachment.
However, NSAttributedString doesn't support rendering arbitrary views.

This change adds support for nesting views within Text by creating one
NSTextAttachment per inline view. The NSTextAttachments act as placeholders.
They are set to be the size of the corresponding view. After the text is
laid out, we query the text system to find out where it has positioned each
NSTextAttachment. We then position the views to be at those locations.

This commit also contains a change in `RCTShadowText.m`
`_setParagraphStyleOnAttributedString:heightOfTallestSubview:`. It now only sets
`lineHeight`, `textAlign`, and `writingDirection` when they've actua
Closes facebook#7304

Differential Revision: D3269333

Pulled By: nicklockwood

fbshipit-source-id: 2b59f1c5445a4012f9c29df9f10f5010060ea517
  • Loading branch information
Adam Comella authored and Morgan Pretty committed Aug 24, 2016
1 parent 226ee98 commit 6488ce2
Show file tree
Hide file tree
Showing 17 changed files with 223 additions and 226 deletions.
12 changes: 10 additions & 2 deletions Examples/UIExplorer/TextExample.ios.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
/**
* Copyright (c) 2013-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.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
Expand Down Expand Up @@ -415,12 +422,13 @@ exports.examples = [
);
},
}, {
title: 'Inline images',
title: 'Inline views',
render: function() {
return (
<View>
<Text>
This text contains an inline image <Image source={require('./flux.png')} style={{width: 30, height: 11, resizeMode: 'cover'}}/>. Neat, huh?
This text contains an inline blue view <View style={{width: 25, height: 25, backgroundColor: 'steelblue'}} /> and
an inline image <Image source={require('./flux.png')} style={{width: 30, height: 11, resizeMode: 'cover'}}/>. Neat, huh?
</Text>
</View>
);
Expand Down
12 changes: 0 additions & 12 deletions Libraries/Image/Image.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,6 @@ var Image = React.createClass({
validAttributes: ReactNativeViewAttributes.UIView
},

contextTypes: {
isInAParentText: React.PropTypes.bool
},

render: function() {
var source = resolveAssetSource(this.props.source) || {};
var {width, height, uri} = source;
Expand All @@ -227,13 +223,6 @@ var Image = React.createClass({
console.warn('The <Image> component requires a `source` property rather than `src`.');
}

if (this.context.isInAParentText) {
RawImage = RCTVirtualImage;
if (!width || !height) {
console.warn('You must specify a width and height for the image %s', uri);
}
}

return (
<RawImage
{...this.props}
Expand All @@ -254,7 +243,6 @@ var styles = StyleSheet.create({

var RCTImageView = requireNativeComponent('RCTImageView', Image);
var RCTNetworkImageView = NetworkImageViewManager ? requireNativeComponent('RCTNetworkImageView', Image) : RCTImageView;
var RCTVirtualImage = requireNativeComponent('RCTVirtualImage', Image);


module.exports = Image;
10 changes: 0 additions & 10 deletions Libraries/Image/RCTImage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtils.m; sourceTree = "<group>"; };
139A38821C4D57AD00862840 /* RCTResizeMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTResizeMode.h; sourceTree = "<group>"; };
139A38831C4D587C00862840 /* RCTResizeMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTResizeMode.m; sourceTree = "<group>"; };
13EF7F071BC42D4E003F47DD /* RCTShadowVirtualImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowVirtualImage.h; sourceTree = "<group>"; };
13EF7F081BC42D4E003F47DD /* RCTShadowVirtualImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowVirtualImage.m; sourceTree = "<group>"; };
13EF7F091BC42D4E003F47DD /* RCTVirtualImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualImageManager.h; sourceTree = "<group>"; };
13EF7F0A1BC42D4E003F47DD /* RCTVirtualImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualImageManager.m; sourceTree = "<group>"; };
13EF7F7D1BC825B1003F47DD /* RCTXCAssetImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTXCAssetImageLoader.h; sourceTree = "<group>"; };
13EF7F7E1BC825B1003F47DD /* RCTXCAssetImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTXCAssetImageLoader.m; sourceTree = "<group>"; };
143879361AAD32A300F088A5 /* RCTImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageLoader.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -95,10 +91,6 @@
35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */,
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */,
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */,
13EF7F071BC42D4E003F47DD /* RCTShadowVirtualImage.h */,
13EF7F081BC42D4E003F47DD /* RCTShadowVirtualImage.m */,
13EF7F091BC42D4E003F47DD /* RCTVirtualImageManager.h */,
13EF7F0A1BC42D4E003F47DD /* RCTVirtualImageManager.m */,
58B5115E1A9E6B3D00147676 /* Products */,
);
indentWidth = 2;
Expand Down Expand Up @@ -169,7 +161,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
13EF7F0C1BC42D4E003F47DD /* RCTVirtualImageManager.m in Sources */,
35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */,
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */,
1304D5B21AA8C50D0002E2BE /* RCTGIFImageDecoder.m in Sources */,
Expand All @@ -178,7 +169,6 @@
139A38841C4D587C00862840 /* RCTResizeMode.m in Sources */,
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */,
EEF314721C9B0DD30049118E /* RCTImageBlurUtils.m in Sources */,
13EF7F0B1BC42D4E003F47DD /* RCTShadowVirtualImage.m in Sources */,
13EF7F7F1BC825B1003F47DD /* RCTXCAssetImageLoader.m in Sources */,
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */,
);
Expand Down
3 changes: 1 addition & 2 deletions Libraries/Image/RCTImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
*/

#import <UIKit/UIKit.h>
#import "RCTImageComponent.h"
#import "RCTResizeMode.h"

@class RCTBridge;
@class RCTImageSource;

@interface RCTImageView : UIImageView <RCTImageComponent>
@interface RCTImageView : UIImageView

- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;

Expand Down
28 changes: 0 additions & 28 deletions Libraries/Image/RCTShadowVirtualImage.h

This file was deleted.

83 changes: 0 additions & 83 deletions Libraries/Image/RCTShadowVirtualImage.m

This file was deleted.

14 changes: 0 additions & 14 deletions Libraries/Image/RCTVirtualImageManager.h

This file was deleted.

25 changes: 0 additions & 25 deletions Libraries/Image/RCTVirtualImageManager.m

This file was deleted.

Loading

0 comments on commit 6488ce2

Please sign in to comment.