CameraRoll模块提供了访问本地相册的功能。在iOS上使用这个模块之前,你需要先链接RCTCameraRoll库,具体做法请参考链接原生库文档。

译注:本模块只提供了基本的访问图片的功能,并没有提供相册界面。对于多数开发者来说,可能第三方的react-native-image-crop-picker的功能更为完整易用(可多选、压缩、裁剪等)。

iOS 10的权限要求

从iOS10开始,访问相册需要用户授权。你需要在Info.plist中添加一条名为NSPhotoLibraryUsageDescription的键,然后在其值中填写向用户请求权限的具体描述。编辑完成后这个键在Xcode中实际会显示为Privacy - Photo Library Usage Description

iOS 11的权限要求

从iOS11开始,如果您的项目有保存图片需求,需要额外申请用户授权。你需要在Info.plist中添加一条名为NSPhotoLibraryAddUsageDescription的键,然后在其值中填写向用户请求权限的具体描述。编辑完成后这个键在Xcode中实际会显示为Privacy - Photo Library Additions Usage Description。而名为NSPhotoLibraryUsageDescription的键此时仅控制相册的读取。具体说明请翻阅官方文档搜索相关键值。

截图

cameraroll

方法

static saveImageWithTag(tag) #

保存一个图片到相册。

@param {string} tag 在安卓上,本参数是一个本地URI,例如"file:///sdcard/img.png".

在iOS设备上可能是以下之一:

  • 本地URI
  • 资源库的标签
  • 非以上两种类型,表示图片数据将会存储在内存中(并且在本进程持续的时候一直会占用内存)。

返回一个Promise,操作成功时返回新的URI。

static saveToCameraRoll(tag, type?) #

把图片或视频保存到相册中。

On Android, the tag must be a local image or video URI, such as "file:///sdcard/img.png".

On iOS, the tag can be any image URI (including local, remote asset-library and base64 data URIs) or a local video file URI (remote or data URIs are not supported for saving video at this time).

If the tag has a file extension of .mov or .mp4, it will be inferred as a video. Otherwise it will be treated as a photo. To override the automatic choice, you can pass an optional type parameter that must be one of 'photo' or 'video'.

Returns a Promise which will resolve with the new URI.

static getPhotos(params: object) #

返回一个带有图片标识符对象的Promise。返回的对象的结构参见getPhotosReturnChecker

@param {object} 要求的参数结构参见getPhotosParamChecker.

返回一个Promise,操作成功时返回符合getPhotosReturnChecker结构的对象。

例子

'use strict';

const React = require('react');
const ReactNative = require('react-native');
const {
  CameraRoll,
  Image,
  Slider,
  StyleSheet,
  Switch,
  Text,
  View,
  TouchableOpacity
} = ReactNative;

const invariant = require('fbjs/lib/invariant');

const CameraRollView = require('./CameraRollView');

const AssetScaledImageExampleView = require('./AssetScaledImageExample');

class CameraRollExample extends React.Component {
  state = {
    groupTypes: 'SavedPhotos',
    sliderValue: 1,
    bigImages: true,
  };
  _cameraRollView: ?CameraRollView;
  render() {
    return (
      <View>
        <Switch
          onValueChange={this._onSwitchChange}
          value={this.state.bigImages}
        />
        <Text>{(this.state.bigImages ? 'Big' : 'Small') + ' Images'}</Text>
        <Slider
          value={this.state.sliderValue}
          onValueChange={this._onSliderChange}
        />
        <Text>{'Group Type: ' + this.state.groupTypes}</Text>
        <CameraRollView
          ref={(ref) => { this._cameraRollView = ref; }}
          batchSize={20}
          groupTypes={this.state.groupTypes}
          renderImage={this._renderImage}
        />
      </View>
    );
  }

  loadAsset = (asset) => {
    if (this.props.navigator) {
      this.props.navigator.push({
        title: 'Camera Roll Image',
        component: AssetScaledImageExampleView,
        backButtonTitle: 'Back',
        passProps: { asset: asset },
      });
    }
  };

  _renderImage = (asset) => {
    const imageSize = this.state.bigImages ? 150 : 75;
    const imageStyle = [styles.image, {width: imageSize, height: imageSize}];
    const {location} = asset.node;
    const locationStr = location ? JSON.stringify(location) : 'Unknown location';
    return (
      <TouchableOpacity key={asset} onPress={ this.loadAsset.bind( this, asset ) }>
        <View style={styles.row}>
          <Image
            source={asset.node.image}
            style={imageStyle}
          />
          <View style={styles.info}>
            <Text style={styles.url}>{asset.node.image.uri}</Text>
            <Text>{locationStr}</Text>
            <Text>{asset.node.group_name}</Text>
            <Text>{new Date(asset.node.timestamp).toString()}</Text>
          </View>
        </View>
      </TouchableOpacity>
    );
  };

  _onSliderChange = (value) => {
    const options = CameraRoll.GroupTypesOptions;
    const index = Math.floor(value * options.length * 0.99);
    const groupTypes = options[index];
    if (groupTypes !== this.state.groupTypes) {
      this.setState({groupTypes: groupTypes});
    }
  };

  _onSwitchChange = (value) => {
    invariant(this._cameraRollView, 'ref should be set');
    this._cameraRollView.rendererChanged();
    this.setState({ bigImages: value });
  };
}

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    flex: 1,
  },
  url: {
    fontSize: 9,
    marginBottom: 14,
  },
  image: {
    margin: 4,
  },
  info: {
    flex: 1,
  },
});

exports.title = 'Camera Roll';
exports.description = 'Example component that uses CameraRoll to list user\'s photos';
exports.examples = [
  {
    title: 'Photos',
    render(): React.Element<any> { return <CameraRollExample />; }
  }
];

书籍推荐