Camera kit initial commit
89
.flowconfig
Normal file
@ -0,0 +1,89 @@
|
||||
[ignore]
|
||||
|
||||
# We fork some components by platform.
|
||||
.*/*.web.js
|
||||
.*/*.android.js
|
||||
|
||||
# Some modules have their own node_modules with overlap
|
||||
.*/node_modules/node-haste/.*
|
||||
|
||||
# Ugh
|
||||
.*/node_modules/babel.*
|
||||
.*/node_modules/babylon.*
|
||||
.*/node_modules/invariant.*
|
||||
|
||||
# Ignore react and fbjs where there are overlaps, but don't ignore
|
||||
# anything that react-native relies on
|
||||
.*/node_modules/fbjs/lib/Map.js
|
||||
.*/node_modules/fbjs/lib/fetch.js
|
||||
.*/node_modules/fbjs/lib/ExecutionEnvironment.js
|
||||
.*/node_modules/fbjs/lib/ErrorUtils.js
|
||||
|
||||
# Flow has a built-in definition for the 'react' module which we prefer to use
|
||||
# over the currently-untyped source
|
||||
.*/node_modules/react/react.js
|
||||
.*/node_modules/react/lib/React.js
|
||||
.*/node_modules/react/lib/ReactDOM.js
|
||||
|
||||
.*/__mocks__/.*
|
||||
.*/__tests__/.*
|
||||
|
||||
.*/commoner/test/source/widget/share.js
|
||||
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
|
||||
# See https://github.com/facebook/flow/issues/442
|
||||
.*/react-tools/node_modules/commoner/lib/reader.js
|
||||
|
||||
# Ignore jest
|
||||
.*/node_modules/jest-cli/.*
|
||||
|
||||
# Ignore Website
|
||||
.*/website/.*
|
||||
|
||||
.*/node_modules/is-my-json-valid/test/.*\.json
|
||||
.*/node_modules/iconv-lite/encodings/tables/.*\.json
|
||||
.*/node_modules/y18n/test/.*\.json
|
||||
.*/node_modules/spdx-license-ids/spdx-license-ids.json
|
||||
.*/node_modules/spdx-exceptions/index.json
|
||||
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
|
||||
.*/node_modules/resolve/lib/core.json
|
||||
.*/node_modules/jsonparse/samplejson/.*\.json
|
||||
.*/node_modules/json5/test/.*\.json
|
||||
.*/node_modules/ua-parser-js/test/.*\.json
|
||||
.*/node_modules/builtin-modules/builtin-modules.json
|
||||
.*/node_modules/binary-extensions/binary-extensions.json
|
||||
.*/node_modules/url-regex/tlds.json
|
||||
.*/node_modules/joi/.*\.json
|
||||
.*/node_modules/isemail/.*\.json
|
||||
.*/node_modules/tr46/.*\.json
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow
|
||||
flow/
|
||||
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
esproposal.class_static_fields=enable
|
||||
esproposal.class_instance_fields=enable
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\)$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
0.22.0
|
||||
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# OSX
|
||||
#
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
*.xccheckout
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# Android/IJ
|
||||
#
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
1
.watchmanconfig
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
126
android/app/build.gradle
Normal file
@ -0,0 +1,126 @@
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
* and bundleReleaseJsAndAssets).
|
||||
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||
* bundle directly from the development server. Below you can see all the possible configurations
|
||||
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||
* `apply from: "react.gradle"` line.
|
||||
*
|
||||
* project.ext.react = [
|
||||
* // the name of the generated asset file containing your JS bundle
|
||||
* bundleAssetName: "index.android.bundle",
|
||||
*
|
||||
* // the entry file for bundle generation
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
* bundleInDebug: false,
|
||||
*
|
||||
* // whether to bundle JS and assets in release mode
|
||||
* bundleInRelease: true,
|
||||
*
|
||||
* // whether to bundle JS and assets in another build variant (if configured).
|
||||
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'bundleIn${productFlavor}${buildType}'
|
||||
* // 'bundleIn${buildType}'
|
||||
* // bundleInFreeDebug: true,
|
||||
* // bundleInPaidRelease: true,
|
||||
* // bundleInBeta: true,
|
||||
*
|
||||
* // the root of your project, i.e. where "package.json" lives
|
||||
* root: "../../",
|
||||
*
|
||||
* // where to put the JS bundle asset in debug mode
|
||||
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||
*
|
||||
* // where to put the JS bundle asset in release mode
|
||||
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in debug mode
|
||||
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in release mode
|
||||
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||
*
|
||||
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||
* // for example, you might want to remove it from here.
|
||||
* inputExcludes: ["android/**", "ios/**"]
|
||||
* ]
|
||||
*/
|
||||
|
||||
apply from: "react.gradle"
|
||||
|
||||
/**
|
||||
* Set this to true to create two separate APKs instead of one:
|
||||
* - An APK that only works on ARM devices
|
||||
* - An APK that only works on x86 devices
|
||||
* The advantage is the size of the APK is reduced by about 4MB.
|
||||
* Upload all the APKs to the Play Store and people will download
|
||||
* the correct one based on the CPU architecture of their device.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
|
||||
/**
|
||||
* Run Proguard to shrink the Java bytecode in release builds.
|
||||
*/
|
||||
def enableProguardInReleaseBuilds = false
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.reactnativecamerakit"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
}
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
|
||||
def versionCodes = ["armeabi-v7a":1, "x86":2]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
}
|
||||
67
android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||
-dontobfuscate
|
||||
|
||||
# React Native
|
||||
|
||||
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||
# See http://sourceforge.net/p/proguard/bugs/466/
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||
|
||||
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||
}
|
||||
|
||||
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
|
||||
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
|
||||
|
||||
-dontwarn com.facebook.react.**
|
||||
|
||||
# okhttp
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keep class com.squareup.okhttp.** { *; }
|
||||
-keep interface com.squareup.okhttp.** { *; }
|
||||
-dontwarn com.squareup.okhttp.**
|
||||
|
||||
# okio
|
||||
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn okio.**
|
||||
|
||||
# stetho
|
||||
|
||||
-dontwarn com.facebook.stetho.**
|
||||
97
android/app/react.gradle
Normal file
@ -0,0 +1,97 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
def config = project.hasProperty("react") ? project.react : [];
|
||||
|
||||
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
|
||||
def entryFile = config.entryFile ?: "index.android.js"
|
||||
|
||||
// because elvis operator
|
||||
def elvisFile(thing) {
|
||||
return thing ? file(thing) : null;
|
||||
}
|
||||
|
||||
def reactRoot = elvisFile(config.root) ?: file("../../")
|
||||
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
|
||||
|
||||
void runBefore(String dependentTaskName, Task task) {
|
||||
Task dependentTask = tasks.findByPath(dependentTaskName);
|
||||
if (dependentTask != null) {
|
||||
dependentTask.dependsOn task
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
// Grab all build types and product flavors
|
||||
def buildTypes = android.buildTypes.collect { type -> type.name }
|
||||
def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
|
||||
|
||||
// When no product flavors defined, use empty
|
||||
if (!productFlavors) productFlavors.add('')
|
||||
|
||||
productFlavors.each { productFlavorName ->
|
||||
buildTypes.each { buildTypeName ->
|
||||
// Create variant and target names
|
||||
def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}"
|
||||
def targetPath = productFlavorName ?
|
||||
"${productFlavorName}/${buildTypeName}" :
|
||||
"${buildTypeName}"
|
||||
|
||||
// React js bundle directories
|
||||
def jsBundleDirConfigName = "jsBundleDir${targetName}"
|
||||
def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
|
||||
file("$buildDir/intermediates/assets/${targetPath}")
|
||||
|
||||
def resourcesDirConfigName = "resourcesDir${targetName}"
|
||||
def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
|
||||
file("$buildDir/intermediates/res/merged/${targetPath}")
|
||||
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
|
||||
|
||||
// Bundle task name for variant
|
||||
def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets"
|
||||
|
||||
def currentBundleTask = tasks.create(
|
||||
name: bundleJsAndAssetsTaskName,
|
||||
type: Exec) {
|
||||
group = "react"
|
||||
description = "bundle JS and assets for ${targetName}."
|
||||
|
||||
// Create dirs if they are not there (e.g. the "clean" task just ran)
|
||||
doFirst {
|
||||
jsBundleDir.mkdirs()
|
||||
resourcesDir.mkdirs()
|
||||
}
|
||||
|
||||
// Set up inputs and outputs so gradle can cache the result
|
||||
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
|
||||
outputs.dir jsBundleDir
|
||||
outputs.dir resourcesDir
|
||||
|
||||
// Set up the call to the react-native cli
|
||||
workingDir reactRoot
|
||||
|
||||
// Set up dev mode
|
||||
def devEnabled = !targetName.toLowerCase().contains("release")
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
commandLine "cmd", "/c", "node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
|
||||
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
|
||||
} else {
|
||||
commandLine "node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
|
||||
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
|
||||
}
|
||||
|
||||
enabled config."bundleIn${targetName}" ||
|
||||
config."bundleIn${buildTypeName.capitalize()}" ?:
|
||||
targetName.toLowerCase().contains("release")
|
||||
}
|
||||
|
||||
// Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
|
||||
currentBundleTask.dependsOn("merge${targetName}Resources")
|
||||
currentBundleTask.dependsOn("merge${targetName}Assets")
|
||||
|
||||
runBefore("processArmeabi-v7a${targetName}Resources", currentBundleTask)
|
||||
runBefore("processX86${targetName}Resources", currentBundleTask)
|
||||
runBefore("processUniversal${targetName}Resources", currentBundleTask)
|
||||
runBefore("process${targetName}Resources", currentBundleTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
android/app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.reactnativecamerakit">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,40 @@
|
||||
package com.reactnativecamerakit;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
/**
|
||||
* Returns the name of the main component registered from JavaScript.
|
||||
* This is used to schedule rendering of the component.
|
||||
*/
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "ReactNativeCameraKit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether dev mode should be enabled.
|
||||
* This enables e.g. the dev menu.
|
||||
*/
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of packages used by the app. If the app uses additional views
|
||||
* or modules besides the default ones, add more packages here.
|
||||
*/
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage()
|
||||
);
|
||||
}
|
||||
}
|
||||
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
3
android/app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">ReactNativeCameraKit</string>
|
||||
</resources>
|
||||
8
android/app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
24
android/build.gradle
Normal file
@ -0,0 +1,24 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url "$projectDir/../../node_modules/react-native/android"
|
||||
}
|
||||
}
|
||||
}
|
||||
20
android/gradle.properties
Normal file
@ -0,0 +1,20 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
android.useDeprecatedNdk=true
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
||||
164
android/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
3
android/settings.gradle
Normal file
@ -0,0 +1,3 @@
|
||||
rootProject.name = 'ReactNativeCameraKit'
|
||||
|
||||
include ':app'
|
||||
51
index.android.js
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
*/
|
||||
|
||||
import React, {
|
||||
AppRegistry,
|
||||
Component,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
class ReactNativeCameraKit extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>
|
||||
Welcome to React Native!
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
To get started, edit index.android.js
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
Shake or press menu button for dev menu
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
},
|
||||
instructions: {
|
||||
textAlign: 'center',
|
||||
color: '#333333',
|
||||
marginBottom: 5,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('ReactNativeCameraKit', () => ReactNativeCameraKit);
|
||||
84
index.ios.js
Normal file
@ -0,0 +1,84 @@
|
||||
import React from 'react-native';
|
||||
|
||||
const {
|
||||
AppRegistry,
|
||||
Component,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
Image,
|
||||
TouchableOpacity,
|
||||
PixelRatio,
|
||||
NativeModules: {
|
||||
ReactNativeCameraKit
|
||||
}
|
||||
} = React;
|
||||
|
||||
class Example extends Component {
|
||||
state = {
|
||||
photoSource: null,
|
||||
error: null
|
||||
};
|
||||
|
||||
selectPhotoTapped() {
|
||||
const options = {
|
||||
message: 'Recent Images',
|
||||
takePhotoActionTitle: 'Take a Photo',
|
||||
pickPhotoActionTitle: 'Gallery',
|
||||
cancelActionTitle: 'Cancel',
|
||||
sendSelectedPhotosTitle: 'Send %lu Photo',
|
||||
aspectRatioInfoMessage: 'Your images look best with 16:9 ratio',
|
||||
aspectRatios: ["16:9", "1:1", "4:3", "3:2", "2:3", "3:4", "9:16"],
|
||||
collectionName: 'eCom'
|
||||
};
|
||||
|
||||
ReactNativeCameraKit.presentPhotoPicker(options, (response) => {
|
||||
if (response.images) {
|
||||
const source = {uri: 'data:image/jpeg;base64,' + response.images[response.images.length -1], isStatic: true};
|
||||
this.setState({
|
||||
photoSource: source
|
||||
});
|
||||
}
|
||||
if (response.error) {
|
||||
this.setState({
|
||||
error: response.error
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
|
||||
<View style={[styles.photo, styles.photoContainer, {marginBottom: 20}]}>
|
||||
{ this.state.photoSource === null ? <Text>Select a Photo</Text> :
|
||||
<Image style={styles.photo} source={this.state.photoSource} />
|
||||
}
|
||||
</View>
|
||||
{ this.state.error ? <Text>this.state.error</Text> : null }
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF'
|
||||
},
|
||||
photoContainer: {
|
||||
borderColor: '#9B9B9B',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderWidth: 1 / PixelRatio.get()
|
||||
},
|
||||
photo: {
|
||||
width: 150,
|
||||
height: 150
|
||||
}
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('ReactNativeCameraKit', () => Example);
|
||||
183
ios/CameraSessionManager.swift
Normal file
@ -0,0 +1,183 @@
|
||||
//
|
||||
// CameraSessionManager.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
enum CameraType {
|
||||
case FrontFacingCamera
|
||||
case BackFacingCamera
|
||||
}
|
||||
|
||||
class CameraSessionManager: NSObject {
|
||||
var captureDevice: AVCaptureDevice!
|
||||
var previewLayer: AVCaptureVideoPreviewLayer!
|
||||
var captureSession: AVCaptureSession!
|
||||
var stillImageOutput: AVCaptureStillImageOutput!
|
||||
var flashMode: AVCaptureFlashMode = .Auto
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
self.captureSession = AVCaptureSession()
|
||||
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh
|
||||
}
|
||||
|
||||
convenience init(cameraType: CameraType) {
|
||||
self.init()
|
||||
|
||||
captureSession.beginConfiguration()
|
||||
initiateCaptureSessionForCamera(cameraType)
|
||||
addStillImageOutput()
|
||||
addVideoPreviewLayer()
|
||||
captureSession.commitConfiguration()
|
||||
}
|
||||
|
||||
internal func addVideoPreviewLayer() {
|
||||
self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) as AVCaptureVideoPreviewLayer
|
||||
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
|
||||
}
|
||||
|
||||
internal func initiateCaptureSessionForCamera(cameraType: CameraType) {
|
||||
let devices = AVCaptureDevice.devices()
|
||||
|
||||
for device in devices {
|
||||
if (device.hasMediaType(AVMediaTypeVideo)) {
|
||||
switch (cameraType) {
|
||||
case .FrontFacingCamera:
|
||||
if (device.position == AVCaptureDevicePosition.Front) {
|
||||
self.captureDevice = device as! AVCaptureDevice
|
||||
}
|
||||
break
|
||||
case .BackFacingCamera:
|
||||
if (device.position == AVCaptureDevicePosition.Back) {
|
||||
self.captureDevice = device as! AVCaptureDevice
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
let possibleCameraInput: AnyObject? = try AVCaptureDeviceInput(device: self.captureDevice)
|
||||
if let cameraInput = possibleCameraInput as? AVCaptureDeviceInput {
|
||||
if self.captureSession.canAddInput(cameraInput) {
|
||||
self.captureSession.addInput(cameraInput)
|
||||
}
|
||||
}
|
||||
} catch let error as NSError {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
func assignVideoOrienationForVideoConnection(videoConnection: AVCaptureConnection) {
|
||||
var newOrientation: AVCaptureVideoOrientation
|
||||
switch (UIDevice.currentDevice().orientation) {
|
||||
case .Portrait:
|
||||
newOrientation = AVCaptureVideoOrientation.Portrait
|
||||
break
|
||||
case .PortraitUpsideDown:
|
||||
newOrientation = AVCaptureVideoOrientation.PortraitUpsideDown
|
||||
break
|
||||
case .LandscapeLeft:
|
||||
newOrientation = AVCaptureVideoOrientation.LandscapeRight
|
||||
break
|
||||
case .LandscapeRight:
|
||||
newOrientation = AVCaptureVideoOrientation.LandscapeLeft
|
||||
break
|
||||
default:
|
||||
newOrientation = AVCaptureVideoOrientation.Portrait
|
||||
}
|
||||
|
||||
videoConnection.videoOrientation = newOrientation
|
||||
}
|
||||
|
||||
func getOrientationAdaptedCaptureConnection() -> AVCaptureConnection?
|
||||
{
|
||||
var videoConnection: AVCaptureConnection? = nil
|
||||
for connection in self.stillImageOutput.connections {
|
||||
for port in connection.inputPorts! {
|
||||
if (port.mediaType == AVMediaTypeVideo) {
|
||||
videoConnection = connection as? AVCaptureConnection
|
||||
self.assignVideoOrienationForVideoConnection(videoConnection!)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (videoConnection != nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return videoConnection
|
||||
}
|
||||
|
||||
internal func addStillImageOutput() {
|
||||
self.stillImageOutput = AVCaptureStillImageOutput()
|
||||
self.stillImageOutput.outputSettings = NSDictionary(objects: [AVVideoCodecJPEG], forKeys: [AVVideoCodecKey]) as! [NSObject : AnyObject]
|
||||
self.getOrientationAdaptedCaptureConnection()
|
||||
if self.captureSession.canAddOutput(self.stillImageOutput) {
|
||||
self.captureSession.addOutput(self.stillImageOutput)
|
||||
}
|
||||
|
||||
do {
|
||||
if (captureDevice.isFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus)) {
|
||||
try captureDevice.lockForConfiguration()
|
||||
if captureDevice.isFlashModeSupported(self.flashMode) {
|
||||
captureDevice.flashMode = self.flashMode
|
||||
}
|
||||
if captureDevice.isFocusModeSupported(.ContinuousAutoFocus) {
|
||||
captureDevice.focusMode = AVCaptureFocusMode.ContinuousAutoFocus
|
||||
}
|
||||
if captureDevice.isWhiteBalanceModeSupported(.ContinuousAutoWhiteBalance) {
|
||||
captureDevice.whiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance
|
||||
}
|
||||
captureDevice.unlockForConfiguration()
|
||||
}
|
||||
} catch let error as NSError {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
internal func captureStillImage(completionHandler: ((UIImage) -> Void)!) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
|
||||
let videoConnection = self.getOrientationAdaptedCaptureConnection()
|
||||
if (videoConnection != nil) {
|
||||
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler:
|
||||
{ (imageSampleBuffer: CMSampleBuffer!, _) -> Void in
|
||||
let stillImageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
|
||||
let stillImage = UIImage(data: stillImageData)
|
||||
|
||||
completionHandler(stillImage!)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func changeFlashMode(mode: AVCaptureFlashMode) {
|
||||
do {
|
||||
if (captureDevice.hasFlash && captureDevice.isFlashModeSupported(mode) && captureDevice.flashMode != mode) {
|
||||
try captureDevice.lockForConfiguration()
|
||||
captureDevice.flashMode = mode
|
||||
self.flashMode = mode
|
||||
captureDevice.unlockForConfiguration()
|
||||
}
|
||||
} catch let error as NSError {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
func stopSession() {
|
||||
self.captureSession.stopRunning()
|
||||
|
||||
for input in self.captureSession.inputs {
|
||||
self.captureSession.removeInput(input as! AVCaptureInput)
|
||||
}
|
||||
|
||||
for output in self.captureSession.outputs {
|
||||
self.captureSession.removeOutput(output as! AVCaptureOutput)
|
||||
}
|
||||
}
|
||||
}
|
||||
385
ios/CameraViewController.swift
Normal file
@ -0,0 +1,385 @@
|
||||
//
|
||||
// CameraViewController.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
import AssetsLibrary
|
||||
import Photos
|
||||
|
||||
struct AspectRatio {
|
||||
let widthRatio: Int
|
||||
let heightRatio: Int
|
||||
|
||||
init(widthRatio: Int, heightRatio: Int) {
|
||||
self.widthRatio = widthRatio
|
||||
self.heightRatio = heightRatio
|
||||
}
|
||||
}
|
||||
|
||||
class CameraViewController : UIViewController, PhotoViewControllerDelegate {
|
||||
var cameraViewControllerDelegate: CameraViewControllerDelegate?
|
||||
|
||||
var cameraManager: CameraSessionManager!
|
||||
var cameraOptions: [String: AnyObject]!
|
||||
let topBarHeight: CGFloat = 50
|
||||
var topBarButtonSize: CGSize!
|
||||
let bottomBarHeight: CGFloat = 115
|
||||
var flashButton: UIButton!
|
||||
let flashModes = ["Auto", "On", "Off"]
|
||||
var flashModeSelector: UISegmentedControl!
|
||||
var ratioField = UITextField()
|
||||
let aspectRatios: [String]
|
||||
var aspectRatio: AspectRatio!
|
||||
var ratioLayer = UIView()
|
||||
var infoLabel: UITextField!
|
||||
|
||||
let flashColor = UIColor(colorLiteralRed: 0.95, green: 0.76, blue: 0.2, alpha: 1)
|
||||
|
||||
let assetCollectionName: String!
|
||||
|
||||
init(cameraOptions: [String: AnyObject]) {
|
||||
self.cameraOptions = cameraOptions
|
||||
self.aspectRatios = cameraOptions["aspectRatios"] as! [String]
|
||||
self.assetCollectionName = cameraOptions["collectionName"] as! String;
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
self.aspectRatio = self.extractRatio(aspectRatios[0])
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func prefersStatusBarHidden() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func shouldAutorotate() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.setupCameraManager(.BackFacingCamera)
|
||||
|
||||
let sessionQueue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL)
|
||||
dispatch_async(sessionQueue) { () -> Void in
|
||||
self.cameraManager.captureSession.startRunning()
|
||||
}
|
||||
|
||||
self.buildUi()
|
||||
}
|
||||
|
||||
private func setupCameraManager(cameraType: CameraType) {
|
||||
self.cameraManager = CameraSessionManager(cameraType: cameraType)
|
||||
self.cameraManager.previewLayer.frame = CGRect(x: 0, y: topBarHeight, width: self.view.frame.size.width, height: self.view.frame.size.height - (topBarHeight + bottomBarHeight))
|
||||
self.view.layer.addSublayer(self.cameraManager.previewLayer)
|
||||
self.fitAspectRatio(aspectRatio)
|
||||
}
|
||||
|
||||
private func buildUi() {
|
||||
topBarButtonSize = CGSizeMake(view.bounds.size.height * 0.04, view.bounds.size.height * 0.04)
|
||||
|
||||
self.addToolbars()
|
||||
self.addShutterButton()
|
||||
self.addCloseButton()
|
||||
self.addFlashButton()
|
||||
self.addFlashModeSelector()
|
||||
self.addRatioSelector()
|
||||
}
|
||||
|
||||
private func addToolbars() {
|
||||
let topBarView = UIView()
|
||||
topBarView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: topBarHeight)
|
||||
topBarView.backgroundColor = UIColor.blackColor()
|
||||
self.view.addSubview(topBarView)
|
||||
|
||||
let bottomBarView = UIView()
|
||||
bottomBarView.frame = CGRect(x: 0, y: self.view.frame.size.height - bottomBarHeight, width: self.view.frame.size.width, height: bottomBarHeight)
|
||||
bottomBarView.backgroundColor = UIColor.blackColor()
|
||||
self.view.addSubview(bottomBarView)
|
||||
}
|
||||
|
||||
private func addShutterButton() {
|
||||
let shutterButtonSize = CGSizeMake(self.view.bounds.size.width * 0.23, self.view.bounds.size.width * 0.23)
|
||||
|
||||
let image = UIImage(named: "ShutterIcon") as UIImage?
|
||||
let button = UIButton(type: UIButtonType.Custom) as UIButton
|
||||
button.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: shutterButtonSize)
|
||||
button.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height - shutterButtonSize.height / 2 - 5)
|
||||
button.setImage(image, forState: .Normal)
|
||||
|
||||
button.addTarget(self, action: "onTakePhoto:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
|
||||
self.view.addSubview(button)
|
||||
}
|
||||
|
||||
private func addCloseButton() {
|
||||
let image = UIImage(named: "CloseIcon") as UIImage?
|
||||
let closeButton = UIButton(type: UIButtonType.Custom) as UIButton
|
||||
closeButton.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: topBarButtonSize)
|
||||
closeButton.center = CGPointMake(topBarButtonSize.width / 2, topBarHeight / 2)
|
||||
closeButton.setImage(image, forState: .Normal)
|
||||
|
||||
closeButton.addTarget(self, action: "onClose:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
|
||||
self.view.addSubview(closeButton)
|
||||
}
|
||||
|
||||
func addFlashButton() {
|
||||
let image = UIImage(named: "FlashAutoIcon") as UIImage?
|
||||
flashButton = UIButton(type: UIButtonType.Custom) as UIButton
|
||||
flashButton.frame = CGRect(origin: CGPoint(x: self.view.bounds.size.width - topBarButtonSize.width, y: 0), size: topBarButtonSize)
|
||||
flashButton.center = CGPointMake(self.view.bounds.size.width - topBarButtonSize.width / 2, topBarHeight / 2)
|
||||
flashButton.setImage(image, forState: .Normal)
|
||||
|
||||
flashButton.addTarget(self, action: "onFlashChange:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
|
||||
self.view.addSubview(flashButton)
|
||||
}
|
||||
|
||||
func addFlashModeSelector() {
|
||||
let controlWidth = 0.6 * self.view.bounds.size.width
|
||||
flashModeSelector = UISegmentedControl(items: flashModes)
|
||||
flashModeSelector.selectedSegmentIndex = 0
|
||||
flashModeSelector.frame = CGRectMake((self.view.bounds.size.width - controlWidth) / 2, 0, controlWidth, topBarHeight)
|
||||
flashModeSelector.backgroundColor = UIColor.clearColor()
|
||||
flashModeSelector.tintColor = UIColor.clearColor()
|
||||
|
||||
flashModeSelector.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.whiteColor()], forState: UIControlState.Normal)
|
||||
flashModeSelector.setTitleTextAttributes([NSForegroundColorAttributeName: flashColor], forState: UIControlState.Selected)
|
||||
|
||||
flashModeSelector.addTarget(self, action: "changeFlashMode:", forControlEvents: .ValueChanged)
|
||||
}
|
||||
|
||||
func addRatioSelector() {
|
||||
let ratioPicker = UIPickerView()
|
||||
ratioPicker.showsSelectionIndicator = true
|
||||
ratioPicker.delegate = self
|
||||
ratioPicker.dataSource = self
|
||||
|
||||
let toolBar = UIToolbar()
|
||||
toolBar.barStyle = UIBarStyle.Default
|
||||
toolBar.tintColor = UIColor.blackColor()
|
||||
toolBar.translucent = true
|
||||
toolBar.sizeToFit()
|
||||
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "onRatioSelected:")
|
||||
toolBar.setItems([doneButton], animated: false)
|
||||
toolBar.userInteractionEnabled = true
|
||||
|
||||
let fieldHeight: CGFloat = 40
|
||||
|
||||
ratioField.tintColor = UIColor.clearColor()
|
||||
ratioField.inputView = ratioPicker
|
||||
ratioField.inputAccessoryView = toolBar
|
||||
ratioField.text = aspectRatios[0]
|
||||
ratioField.frame = CGRectMake(self.view.frame.size.width * 0.85, self.view.frame.size.height - bottomBarHeight, self.view.frame.size.width * 0.15, fieldHeight)
|
||||
ratioField.textAlignment = NSTextAlignment.Right
|
||||
ratioField.contentVerticalAlignment = UIControlContentVerticalAlignment.Center
|
||||
ratioField.textColor = flashColor
|
||||
self.view.addSubview(ratioField)
|
||||
self.view.addSubview(ratioLayer)
|
||||
|
||||
infoLabel = UITextField()
|
||||
infoLabel.text = cameraOptions["aspectRatioInfoMessage"] as! String
|
||||
infoLabel.adjustsFontSizeToFitWidth = true
|
||||
infoLabel.textColor = UIColor.whiteColor()
|
||||
infoLabel.textAlignment = NSTextAlignment.Left
|
||||
infoLabel.frame = CGRectMake(0, self.view.frame.size.height - bottomBarHeight, self.view.frame.size.width * 0.75, fieldHeight)
|
||||
infoLabel.inputView = ratioPicker
|
||||
infoLabel.inputAccessoryView = toolBar
|
||||
self.view.addSubview(infoLabel)
|
||||
}
|
||||
|
||||
private func fitAspectRatio(aspectRatio: AspectRatio) {
|
||||
let previewLayerExcess = CropHelper.cropRectangleToFitRatio(self.cameraManager.previewLayer.frame.width, originalRectangleHeight: self.cameraManager.previewLayer.frame.height, widthRatio: aspectRatio.widthRatio, heightRatio: aspectRatio.heightRatio)
|
||||
|
||||
let backgroundColor = UIColor(white: 0, alpha: 0.5)
|
||||
|
||||
self.ratioLayer.removeFromSuperview()
|
||||
self.ratioLayer = UIView(frame: CGRect(origin: self.cameraManager.previewLayer.frame.origin, size: self.cameraManager.previewLayer.frame.size))
|
||||
self.view.addSubview(self.ratioLayer)
|
||||
|
||||
if (previewLayerExcess.verticalExcess != 0.0) {
|
||||
let topExcess = UIView()
|
||||
topExcess.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: self.cameraManager.previewLayer.frame.width, height: previewLayerExcess.verticalExcess / 2))
|
||||
topExcess.backgroundColor = backgroundColor
|
||||
self.ratioLayer.addSubview(topExcess)
|
||||
|
||||
let bottomExcess = UIView()
|
||||
bottomExcess.frame = CGRect(x: self.cameraManager.previewLayer.frame.origin.x, y: self.cameraManager.previewLayer.frame.height - previewLayerExcess.verticalExcess / 2, width: self.cameraManager.previewLayer.frame.width, height: previewLayerExcess.verticalExcess / 2)
|
||||
bottomExcess.backgroundColor = backgroundColor
|
||||
self.ratioLayer.addSubview(bottomExcess)
|
||||
} else {
|
||||
let leftExcess = UIView()
|
||||
leftExcess.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: previewLayerExcess.horizontalExcess / 2, height: self.cameraManager.previewLayer.frame.height))
|
||||
leftExcess.backgroundColor = backgroundColor
|
||||
self.ratioLayer.addSubview(leftExcess)
|
||||
|
||||
let rightExcess = UIView()
|
||||
rightExcess.frame = CGRect(x: self.cameraManager.previewLayer.frame.origin.x + self.cameraManager.previewLayer.frame.width - previewLayerExcess.horizontalExcess / 2, y: 0, width: previewLayerExcess.horizontalExcess / 2, height: self.cameraManager.previewLayer.frame.height)
|
||||
rightExcess.backgroundColor = backgroundColor
|
||||
self.ratioLayer.addSubview(rightExcess)
|
||||
}
|
||||
}
|
||||
|
||||
func onFlashChange(sender: UIButton) {
|
||||
sender.selected = !sender.selected
|
||||
if sender.selected {
|
||||
flashButton.setImage(UIImage(named: "FlashAutoIcon") as UIImage?, forState: .Normal)
|
||||
self.view.addSubview(flashModeSelector)
|
||||
} else {
|
||||
flashModeSelector.removeFromSuperview()
|
||||
setFlashIcon()
|
||||
}
|
||||
}
|
||||
|
||||
func onRatioSelected(sender: UIButton) {
|
||||
self.ratioField.resignFirstResponder()
|
||||
self.infoLabel.resignFirstResponder()
|
||||
}
|
||||
|
||||
func changeFlashMode(_: UISegmentedControl) {
|
||||
setFlashIcon()
|
||||
flashButton.selected = false
|
||||
flashModeSelector.removeFromSuperview()
|
||||
}
|
||||
|
||||
private func setFlashIcon() {
|
||||
switch flashModeSelector.selectedSegmentIndex {
|
||||
case 1:
|
||||
cameraManager.changeFlashMode(.On)
|
||||
flashButton.setImage(UIImage(named: "FlashOnIcon") as UIImage?, forState: .Normal)
|
||||
break
|
||||
case 2:
|
||||
cameraManager.changeFlashMode(.Off)
|
||||
flashButton.setImage(UIImage(named: "FlashOffIcon") as UIImage?, forState: .Normal)
|
||||
break
|
||||
default:
|
||||
cameraManager.changeFlashMode(.Auto)
|
||||
flashButton.setImage(UIImage(named: "FlashAutoIcon") as UIImage?, forState: .Normal)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func onTakePhoto(sender: UIButton) {
|
||||
self.cameraManager.captureStillImage({ (image: UIImage) -> Void in
|
||||
let croppedImage = self.cropImage(image)
|
||||
self.showPhotoViewController(croppedImage)
|
||||
})
|
||||
}
|
||||
|
||||
func onClose(sender: UIButton) {
|
||||
self.cameraManager.stopSession()
|
||||
//dismissViewControllerAnimated(true, completion: nil)
|
||||
if let delegate = self.cameraViewControllerDelegate {
|
||||
delegate.cameraViewControllerDidCancel(self)
|
||||
}
|
||||
}
|
||||
|
||||
func showPhotoViewController(image: UIImage) {
|
||||
let photoViewController = PhotoViewController(image: image)
|
||||
photoViewController.delegate = self
|
||||
photoViewController.view.bounds = self.view.bounds
|
||||
self.addChildViewController(photoViewController)
|
||||
self.view.addSubview(photoViewController.view)
|
||||
photoViewController.didMoveToParentViewController(self)
|
||||
}
|
||||
|
||||
func hidePhotoViewController(controller: PhotoViewController) {
|
||||
controller.willMoveToParentViewController(nil)
|
||||
controller.view.removeFromSuperview()
|
||||
controller.removeFromParentViewController()
|
||||
}
|
||||
|
||||
//PhotoViewControllerDelegate
|
||||
|
||||
func retakePhoto(controller: PhotoViewController) {
|
||||
self.hidePhotoViewController(controller)
|
||||
}
|
||||
|
||||
func usePhoto(controller: PhotoViewController, photo: UIImage) {
|
||||
dismissViewControllerAnimated(true, completion: nil)
|
||||
let imageData = UIImageJPEGRepresentation(photo, 1.0)
|
||||
let base64 = imageData!.base64EncodedStringWithOptions([])
|
||||
|
||||
var assetCollection: PHAssetCollection?
|
||||
var assetCollectionPlaceholder: PHObjectPlaceholder?
|
||||
|
||||
let fetchOptions = PHFetchOptions()
|
||||
fetchOptions.predicate = NSPredicate(format: "title = %@", self.assetCollectionName)
|
||||
let collection : PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)
|
||||
if let _: AnyObject = collection.firstObject {
|
||||
assetCollection = collection.firstObject as? PHAssetCollection
|
||||
savePhoto(base64, photo: photo, assetCollection: assetCollection!)
|
||||
} else {
|
||||
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
|
||||
let createAlbumRequest : PHAssetCollectionChangeRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(self.assetCollectionName)
|
||||
assetCollectionPlaceholder = createAlbumRequest.placeholderForCreatedAssetCollection
|
||||
}, completionHandler: { success, error in
|
||||
if (success) {
|
||||
let collectionFetchResult = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([assetCollectionPlaceholder!.localIdentifier], options: nil)
|
||||
assetCollection = collectionFetchResult.firstObject as? PHAssetCollection
|
||||
self.savePhoto(base64, photo: photo, assetCollection: assetCollection!)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func savePhoto(imageData: String, photo: UIImage, assetCollection: PHAssetCollection) {
|
||||
PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
|
||||
let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(photo)
|
||||
let assetPlaceholder = assetRequest.placeholderForCreatedAsset
|
||||
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: assetCollection)
|
||||
albumChangeRequest!.addAssets([assetPlaceholder!])
|
||||
}, completionHandler: { (success, error) -> Void in
|
||||
self.cameraManager.stopSession()
|
||||
if let delegate = self.cameraViewControllerDelegate {
|
||||
if success {
|
||||
delegate.imageHasBeenTaken(self, imageData: imageData)
|
||||
} else {
|
||||
delegate.onError(self, error: (error?.localizedDescription)!)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func cropImage(image: UIImage) -> UIImage {
|
||||
let barPart: CGFloat = (topBarHeight + bottomBarHeight) / self.view.bounds.size.height
|
||||
return CropHelper.cropImage(image, widthRatio: aspectRatio.widthRatio, heightRatio: aspectRatio.heightRatio, verticalPartToCrop: barPart)
|
||||
}
|
||||
|
||||
func extractRatio(ratioString: String) -> AspectRatio {
|
||||
let ratios = ratioString.characters.split{$0 == ":"}.map(String.init)
|
||||
return AspectRatio(widthRatio: Int(ratios[0])!, heightRatio: Int(ratios[1])!)
|
||||
}
|
||||
}
|
||||
|
||||
extension CameraViewController: UIPickerViewDataSource {
|
||||
func numberOfComponentsInPickerView(colorPicker: UIPickerView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
return aspectRatios.count
|
||||
}
|
||||
}
|
||||
|
||||
extension CameraViewController: UIPickerViewDelegate {
|
||||
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
||||
return aspectRatios[row]
|
||||
}
|
||||
|
||||
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
|
||||
ratioField.text = aspectRatios[row]
|
||||
self.aspectRatio = self.extractRatio(aspectRatios[row])
|
||||
self.fitAspectRatio(self.aspectRatio)
|
||||
}
|
||||
}
|
||||
13
ios/CameraViewControllerDelegate.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// CameraViewControllerDelegate.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
protocol CameraViewControllerDelegate : NSObjectProtocol {
|
||||
func imageHasBeenTaken(controller: CameraViewController, imageData: String)
|
||||
func cameraViewControllerDidCancel(controller: CameraViewController)
|
||||
func onError(controller: CameraViewController, error: String)
|
||||
}
|
||||
58
ios/CropHelper.swift
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// CropHelper.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
import UIKit
|
||||
|
||||
struct CropInfo {
|
||||
var verticalExcess: CGFloat
|
||||
var horizontalExcess: CGFloat
|
||||
|
||||
init(verticalExcess: CGFloat, horizontalExcess: CGFloat) {
|
||||
self.verticalExcess = verticalExcess
|
||||
self.horizontalExcess = horizontalExcess
|
||||
}
|
||||
}
|
||||
|
||||
class CropHelper: NSObject {
|
||||
static func cropImage(image: UIImage, widthRatio: Int, heightRatio: Int, verticalPartToCrop: CGFloat = 0) -> UIImage {
|
||||
let contextImage: UIImage = UIImage(CGImage: image.CGImage!)
|
||||
let contextSize: CGSize = contextImage.size
|
||||
|
||||
let offset = verticalPartToCrop * contextSize.width
|
||||
let cropInfo = cropRectangleToFitRatio(contextSize.width - offset, originalRectangleHeight: contextSize.height, widthRatio: heightRatio, heightRatio: widthRatio)
|
||||
|
||||
let rect = CGRectMake(offset / 2 + cropInfo.horizontalExcess / 2, cropInfo.verticalExcess / 2, contextSize.width - (offset + cropInfo.horizontalExcess), contextSize.height - cropInfo.verticalExcess)
|
||||
let imageRef = CGImageCreateWithImageInRect(contextImage.CGImage, rect)
|
||||
let newImage = UIImage(CGImage: imageRef!, scale: image.scale, orientation: image.imageOrientation)
|
||||
|
||||
return newImage
|
||||
}
|
||||
|
||||
static func cropRectangleToFitRatio(originalRectangleWidth: CGFloat, originalRectangleHeight: CGFloat, widthRatio: Int, heightRatio: Int) -> CropInfo {
|
||||
var newHeight = originalRectangleHeight
|
||||
var newWidth = originalRectangleWidth
|
||||
|
||||
if (widthRatio > heightRatio) {
|
||||
newHeight = originalRectangleWidth * CGFloat(heightRatio) / CGFloat(widthRatio)
|
||||
} else {
|
||||
if (widthRatio < heightRatio) {
|
||||
newWidth = originalRectangleHeight * CGFloat(widthRatio) / CGFloat(heightRatio)
|
||||
} else {
|
||||
if (originalRectangleWidth > originalRectangleHeight) {
|
||||
newWidth = originalRectangleHeight
|
||||
} else {
|
||||
newHeight = originalRectangleWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CropInfo(verticalExcess: originalRectangleHeight - newHeight, horizontalExcess: originalRectangleWidth - newWidth)
|
||||
}
|
||||
}
|
||||
|
||||
78
ios/PhotoViewController.swift
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// PhotoViewController.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
class PhotoViewController: UIViewController {
|
||||
let image: UIImage
|
||||
var delegate: PhotoViewControllerDelegate?
|
||||
|
||||
let topBarHeight: CGFloat = 50
|
||||
let bottomBarHeight: CGFloat = 50
|
||||
let buttonMargin: CGFloat = 10
|
||||
|
||||
init(image: UIImage) {
|
||||
self.image = image
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func prefersStatusBarHidden() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
var imageViewWidth, imageViewHeight: CGFloat
|
||||
let imageView = UIImageView(image: self.image)
|
||||
if (image.size.width >= image.size.height) {
|
||||
imageViewWidth = self.view.frame.size.width
|
||||
imageViewHeight = imageViewWidth * image.size.height / image.size.width
|
||||
} else {
|
||||
imageViewHeight = self.view.frame.size.height - (topBarHeight + bottomBarHeight)
|
||||
imageViewWidth = imageViewHeight * image.size.width / image.size.height
|
||||
}
|
||||
imageView.frame = CGRectMake(self.view.frame.size.width / 2 - imageViewWidth / 2, self.view.frame.size.height / 2 - imageViewHeight / 2, imageViewWidth, imageViewHeight)
|
||||
self.view.backgroundColor = UIColor.blackColor()
|
||||
self.view.addSubview(imageView)
|
||||
|
||||
let retakePhoto = "Retake"
|
||||
let retakeButton = UIButton(type: UIButtonType.Custom) as UIButton
|
||||
retakeButton.setTitle(retakePhoto, forState: .Normal)
|
||||
retakeButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
|
||||
let retakeLabelSize = retakePhoto.sizeWithAttributes([NSFontAttributeName: retakeButton.titleLabel!.font])
|
||||
retakeButton.frame = CGRect(origin: CGPoint(x: 0, y: self.view.frame.size.height - bottomBarHeight), size: CGSize(width: retakeLabelSize.width + 2 * buttonMargin, height: bottomBarHeight))
|
||||
retakeButton.addTarget(self, action: "onRetakePhoto:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
self.view.addSubview(retakeButton)
|
||||
|
||||
let usePhoto = "Use Photo"
|
||||
let useButton = UIButton(type: UIButtonType.Custom) as UIButton
|
||||
useButton.setTitle(usePhoto, forState: .Normal)
|
||||
useButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
|
||||
let useLabelSize = usePhoto.sizeWithAttributes([NSFontAttributeName: useButton.titleLabel!.font])
|
||||
let useButtonWidth = useLabelSize.width + 2 * buttonMargin
|
||||
useButton.frame = CGRect(origin: CGPoint(x: self.view.frame.size.width - useButtonWidth, y: self.view.frame.size.height - bottomBarHeight), size: CGSize(width: useButtonWidth, height: bottomBarHeight))
|
||||
useButton.addTarget(self, action: "onUsePhoto:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
self.view.addSubview(useButton)
|
||||
}
|
||||
|
||||
func onRetakePhoto(sender: UIButton) {
|
||||
if let delegate = self.delegate {
|
||||
delegate.retakePhoto(self)
|
||||
}
|
||||
}
|
||||
|
||||
func onUsePhoto(sender: UIButton) {
|
||||
if let delegate = self.delegate {
|
||||
delegate.usePhoto(self, photo: image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
ios/PhotoViewControllerDelegate.swift
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// PhotoViewControllerDelegate.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
protocol PhotoViewControllerDelegate : NSObjectProtocol {
|
||||
func retakePhoto(controller: PhotoViewController)
|
||||
func usePhoto(controller: PhotoViewController, photo: UIImage)
|
||||
}
|
||||
13
ios/Podfile
Normal file
@ -0,0 +1,13 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '8.0'
|
||||
# Uncomment this line if you're using Swift
|
||||
use_frameworks!
|
||||
|
||||
target 'ReactNativeCameraKit' do
|
||||
pod "ImagePickerSheetController"
|
||||
end
|
||||
|
||||
target 'ReactNativeCameraKitTests' do
|
||||
|
||||
end
|
||||
|
||||
10
ios/Podfile.lock
Normal file
@ -0,0 +1,10 @@
|
||||
PODS:
|
||||
- ImagePickerSheetController (0.9.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- ImagePickerSheetController
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
ImagePickerSheetController: 3c58c9fee6dcf36485222358a021f6b734f997ba
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
@ -0,0 +1,80 @@
|
||||
//
|
||||
// AnimationController.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 25/05/15.
|
||||
// Copyright (c) 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AnimationController: NSObject {
|
||||
|
||||
let imagePickerSheetController: ImagePickerSheetController
|
||||
let presenting: Bool
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(imagePickerSheetController: ImagePickerSheetController, presenting: Bool) {
|
||||
self.imagePickerSheetController = imagePickerSheetController
|
||||
self.presenting = presenting
|
||||
}
|
||||
|
||||
// MARK: - Animation
|
||||
|
||||
private func animatePresentation(context: UIViewControllerContextTransitioning) {
|
||||
guard let containerView = context.containerView() else {
|
||||
return
|
||||
}
|
||||
|
||||
containerView.addSubview(imagePickerSheetController.view)
|
||||
|
||||
let sheetOriginY = imagePickerSheetController.sheetCollectionView.frame.origin.y
|
||||
imagePickerSheetController.sheetCollectionView.frame.origin.y = containerView.bounds.maxY
|
||||
imagePickerSheetController.backgroundView.alpha = 0
|
||||
|
||||
UIView.animateWithDuration(transitionDuration(context), delay: 0, options: .CurveEaseOut, animations: { () -> Void in
|
||||
self.imagePickerSheetController.sheetCollectionView.frame.origin.y = sheetOriginY
|
||||
self.imagePickerSheetController.backgroundView.alpha = 1
|
||||
}, completion: { _ in
|
||||
context.completeTransition(true)
|
||||
})
|
||||
}
|
||||
|
||||
private func animateDismissal(context: UIViewControllerContextTransitioning) {
|
||||
guard let containerView = context.containerView() else {
|
||||
return
|
||||
}
|
||||
|
||||
UIView.animateWithDuration(transitionDuration(context), delay: 0, options: .CurveEaseIn, animations: { () -> Void in
|
||||
self.imagePickerSheetController.sheetCollectionView.frame.origin.y = containerView.bounds.maxY
|
||||
self.imagePickerSheetController.backgroundView.alpha = 0
|
||||
}, completion: { _ in
|
||||
self.imagePickerSheetController.view.removeFromSuperview()
|
||||
context.completeTransition(true)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UIViewControllerAnimatedTransitioning
|
||||
extension AnimationController: UIViewControllerAnimatedTransitioning {
|
||||
|
||||
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
|
||||
guard #available(iOS 9, *) else {
|
||||
return 0.3
|
||||
}
|
||||
|
||||
return 0.25
|
||||
}
|
||||
|
||||
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
if presenting {
|
||||
animatePresentation(transitionContext)
|
||||
}
|
||||
else {
|
||||
animateDismissal(transitionContext)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
//
|
||||
// ImagePickerAction.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 24/05/15.
|
||||
// Copyright (c) 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum ImagePickerActionStyle {
|
||||
case Default
|
||||
case Cancel
|
||||
}
|
||||
|
||||
public class ImagePickerAction {
|
||||
|
||||
public typealias Title = Int -> String
|
||||
public typealias Handler = (ImagePickerAction) -> ()
|
||||
public typealias SecondaryHandler = (ImagePickerAction, Int) -> ()
|
||||
|
||||
/// The title of the action's button.
|
||||
public let title: String
|
||||
|
||||
/// The title of the action's button when more than one image is selected.
|
||||
public let secondaryTitle: Title
|
||||
|
||||
/// The style of the action. This is used to call a cancel handler when dismissing the controller by tapping the background.
|
||||
public let style: ImagePickerActionStyle
|
||||
|
||||
let handler: Handler
|
||||
let secondaryHandler: SecondaryHandler
|
||||
|
||||
/// Initializes a new ImagePickerAction. The secondary title and handler are used when at least 1 image has been selected.
|
||||
/// Secondary title defaults to title if not specified.
|
||||
/// Secondary handler defaults to handler if not specified.
|
||||
public convenience init(title: String, secondaryTitle: String? = nil, style: ImagePickerActionStyle = .Default, handler: Handler, secondaryHandler: SecondaryHandler? = nil) {
|
||||
self.init(title: title, secondaryTitle: secondaryTitle.map { string in { _ in string }}, style: style, handler: handler, secondaryHandler: secondaryHandler)
|
||||
}
|
||||
|
||||
/// Initializes a new ImagePickerAction. The secondary title and handler are used when at least 1 image has been selected.
|
||||
/// Secondary title defaults to title if not specified. Use the closure to format a title according to the selection.
|
||||
/// Secondary handler defaults to handler if not specified
|
||||
public init(title: String, secondaryTitle: Title?, style: ImagePickerActionStyle = .Default, handler: Handler, var secondaryHandler: SecondaryHandler? = nil) {
|
||||
if secondaryHandler == nil {
|
||||
secondaryHandler = { action, _ in
|
||||
handler(action)
|
||||
}
|
||||
}
|
||||
|
||||
self.title = title
|
||||
self.secondaryTitle = secondaryTitle ?? { _ in title }
|
||||
self.style = style
|
||||
self.handler = handler
|
||||
self.secondaryHandler = secondaryHandler!
|
||||
}
|
||||
|
||||
func handle(numberOfImages: Int = 0) {
|
||||
if numberOfImages > 0 {
|
||||
secondaryHandler(self, numberOfImages)
|
||||
}
|
||||
else {
|
||||
handler(self)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func ?? (left: ImagePickerAction.Title?, right: ImagePickerAction.Title) -> ImagePickerAction.Title {
|
||||
if let left = left {
|
||||
return left
|
||||
}
|
||||
|
||||
return right
|
||||
}
|
||||
@ -0,0 +1,482 @@
|
||||
//
|
||||
// ImagePickerController.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 24/05/15.
|
||||
// Copyright (c) 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Photos
|
||||
|
||||
private let previewCollectionViewInset: CGFloat = 5
|
||||
|
||||
/// The media type an instance of ImagePickerSheetController can display
|
||||
public enum ImagePickerMediaType {
|
||||
case Image
|
||||
case Video
|
||||
case ImageAndVideo
|
||||
}
|
||||
|
||||
@available(iOS 8.0, *)
|
||||
public class ImagePickerSheetController: UIViewController {
|
||||
|
||||
private lazy var sheetController: SheetController = {
|
||||
let controller = SheetController(previewCollectionView: self.previewCollectionView)
|
||||
controller.actionHandlingCallback = { [weak self] in
|
||||
self?.dismissViewControllerAnimated(true, completion: nil)
|
||||
}
|
||||
|
||||
return controller
|
||||
}()
|
||||
|
||||
var sheetCollectionView: UICollectionView {
|
||||
return sheetController.sheetCollectionView
|
||||
}
|
||||
|
||||
private(set) lazy var previewCollectionView: PreviewCollectionView = {
|
||||
let collectionView = PreviewCollectionView()
|
||||
collectionView.accessibilityIdentifier = "ImagePickerSheetPreview"
|
||||
collectionView.backgroundColor = .clearColor()
|
||||
collectionView.allowsMultipleSelection = true
|
||||
collectionView.imagePreviewLayout.sectionInset = UIEdgeInsetsMake(previewCollectionViewInset, previewCollectionViewInset, previewCollectionViewInset, previewCollectionViewInset)
|
||||
collectionView.imagePreviewLayout.showsSupplementaryViews = false
|
||||
collectionView.dataSource = self
|
||||
collectionView.delegate = self
|
||||
collectionView.showsHorizontalScrollIndicator = false
|
||||
collectionView.alwaysBounceHorizontal = true
|
||||
collectionView.registerClass(PreviewCollectionViewCell.self, forCellWithReuseIdentifier: NSStringFromClass(PreviewCollectionViewCell.self))
|
||||
collectionView.registerClass(PreviewSupplementaryView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: NSStringFromClass(PreviewSupplementaryView.self))
|
||||
|
||||
return collectionView
|
||||
}()
|
||||
|
||||
private var supplementaryViews = [Int: PreviewSupplementaryView]()
|
||||
|
||||
lazy var backgroundView: UIView = {
|
||||
let view = UIView()
|
||||
view.accessibilityIdentifier = "ImagePickerSheetBackground"
|
||||
view.backgroundColor = UIColor(white: 0.0, alpha: 0.3961)
|
||||
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "cancel"))
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
/// All the actions. The first action is shown at the top.
|
||||
public var actions: [ImagePickerAction] {
|
||||
return sheetController.actions
|
||||
}
|
||||
|
||||
/// Maximum selection of images.
|
||||
public var maximumSelection: Int?
|
||||
|
||||
private var selectedImageIndices = [Int]() {
|
||||
didSet {
|
||||
sheetController.numberOfSelectedImages = selectedImageIndices.count
|
||||
}
|
||||
}
|
||||
|
||||
/// The selected image assets
|
||||
public var selectedImageAssets: [PHAsset] {
|
||||
return selectedImageIndices.map { self.assets[$0] }
|
||||
}
|
||||
|
||||
/// The media type of the displayed assets
|
||||
public let mediaType: ImagePickerMediaType
|
||||
|
||||
private var assets = [PHAsset]()
|
||||
|
||||
private lazy var requestOptions: PHImageRequestOptions = {
|
||||
let options = PHImageRequestOptions()
|
||||
options.deliveryMode = .HighQualityFormat
|
||||
options.resizeMode = .Fast
|
||||
|
||||
return options
|
||||
}()
|
||||
|
||||
private let imageManager = PHCachingImageManager()
|
||||
|
||||
/// Whether the image preview has been elarged. This is the case when at least once
|
||||
/// image has been selected.
|
||||
public private(set) var enlargedPreviews = false
|
||||
|
||||
private let minimumPreviewHeight: CGFloat = 129
|
||||
private var maximumPreviewHeight: CGFloat = 129
|
||||
|
||||
private var previewCheckmarkInset: CGFloat {
|
||||
guard #available(iOS 9, *) else {
|
||||
return 3.5
|
||||
}
|
||||
|
||||
return 12.5
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
public init(mediaType: ImagePickerMediaType) {
|
||||
self.mediaType = mediaType
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
initialize()
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
self.mediaType = .ImageAndVideo
|
||||
super.init(coder: aDecoder)
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
modalPresentationStyle = .Custom
|
||||
transitioningDelegate = self
|
||||
|
||||
NSNotificationCenter.defaultCenter().addObserver(self, selector: "cancel", name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override public func loadView() {
|
||||
super.loadView()
|
||||
|
||||
view.addSubview(backgroundView)
|
||||
view.addSubview(sheetCollectionView)
|
||||
}
|
||||
|
||||
public override func viewWillAppear(animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
preferredContentSize = CGSize(width: 400, height: view.frame.height)
|
||||
|
||||
if PHPhotoLibrary.authorizationStatus() == .Authorized {
|
||||
prepareAssets()
|
||||
}
|
||||
}
|
||||
|
||||
public override func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if PHPhotoLibrary.authorizationStatus() == .NotDetermined {
|
||||
PHPhotoLibrary.requestAuthorization() { status in
|
||||
if status == .Authorized {
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
self.prepareAssets()
|
||||
self.previewCollectionView.reloadData()
|
||||
self.sheetCollectionView.reloadData()
|
||||
self.view.setNeedsLayout()
|
||||
|
||||
// Explicitely disable animations so it wouldn't animate either
|
||||
// if it was in a popover
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
self.view.layoutIfNeeded()
|
||||
CATransaction.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
/// Adds an new action.
|
||||
/// If the passed action is of type Cancel, any pre-existing Cancel actions will be removed.
|
||||
/// Always arranges the actions so that the Cancel action appears at the bottom.
|
||||
public func addAction(action: ImagePickerAction) {
|
||||
sheetController.addAction(action)
|
||||
view.setNeedsLayout()
|
||||
}
|
||||
|
||||
@objc private func cancel() {
|
||||
sheetController.handleCancelAction()
|
||||
}
|
||||
|
||||
// MARK: - Images
|
||||
|
||||
private func sizeForAsset(asset: PHAsset, scale: CGFloat = 1) -> CGSize {
|
||||
let proportion = CGFloat(asset.pixelWidth)/CGFloat(asset.pixelHeight)
|
||||
|
||||
let imageHeight = maximumPreviewHeight - 2 * previewCollectionViewInset
|
||||
let imageWidth = floor(proportion * imageHeight)
|
||||
|
||||
return CGSize(width: imageWidth * scale, height: imageHeight * scale)
|
||||
}
|
||||
|
||||
private func prepareAssets() {
|
||||
fetchAssets()
|
||||
reloadMaximumPreviewHeight()
|
||||
reloadCurrentPreviewHeight(invalidateLayout: false)
|
||||
|
||||
// Filter out the assets that are too thin. This can't be done before becuase
|
||||
// we don't know how tall the images should be
|
||||
let minImageWidth = 2 * previewCheckmarkInset + (PreviewSupplementaryView.checkmarkImage?.size.width ?? 0)
|
||||
assets = assets.filter { asset in
|
||||
let size = sizeForAsset(asset)
|
||||
return size.width >= minImageWidth
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchAssets() {
|
||||
let options = PHFetchOptions()
|
||||
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
||||
|
||||
switch mediaType {
|
||||
case .Image:
|
||||
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
|
||||
case .Video:
|
||||
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Video.rawValue)
|
||||
case .ImageAndVideo:
|
||||
options.predicate = NSPredicate(format: "mediaType = %d OR mediaType = %d", PHAssetMediaType.Image.rawValue, PHAssetMediaType.Video.rawValue)
|
||||
}
|
||||
|
||||
let fetchLimit = 50
|
||||
if #available(iOS 9, *) {
|
||||
options.fetchLimit = fetchLimit
|
||||
}
|
||||
|
||||
let result = PHAsset.fetchAssetsWithOptions(options)
|
||||
let requestOptions = PHImageRequestOptions()
|
||||
requestOptions.synchronous = true
|
||||
requestOptions.deliveryMode = .FastFormat
|
||||
|
||||
result.enumerateObjectsUsingBlock { asset, _, stop in
|
||||
defer {
|
||||
if self.assets.count > fetchLimit {
|
||||
stop.initialize(true)
|
||||
}
|
||||
}
|
||||
|
||||
if let asset = asset as? PHAsset {
|
||||
self.imageManager.requestImageDataForAsset(asset, options: requestOptions) { data, _, _, info in
|
||||
if data != nil {
|
||||
self.assets.append(asset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func requestImageForAsset(asset: PHAsset, completion: (image: UIImage?) -> ()) {
|
||||
let targetSize = sizeForAsset(asset, scale: UIScreen.mainScreen().scale)
|
||||
requestOptions.synchronous = true
|
||||
|
||||
// Workaround because PHImageManager.requestImageForAsset doesn't work for burst images
|
||||
if asset.representsBurst {
|
||||
imageManager.requestImageDataForAsset(asset, options: requestOptions) { data, _, _, _ in
|
||||
let image = data.flatMap { UIImage(data: $0) }
|
||||
completion(image: image)
|
||||
}
|
||||
}
|
||||
else {
|
||||
imageManager.requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: requestOptions) { image, _ in
|
||||
completion(image: image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func prefetchImagesForAsset(asset: PHAsset) {
|
||||
let targetSize = sizeForAsset(asset, scale: UIScreen.mainScreen().scale)
|
||||
imageManager.startCachingImagesForAssets([asset], targetSize: targetSize, contentMode: .AspectFill, options: requestOptions)
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
public override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
backgroundView.frame = view.bounds
|
||||
|
||||
reloadMaximumPreviewHeight()
|
||||
reloadCurrentPreviewHeight(invalidateLayout: true)
|
||||
|
||||
let sheetHeight = sheetController.preferredSheetHeight
|
||||
let sheetSize = CGSize(width: view.bounds.width, height: sheetHeight)
|
||||
|
||||
// This particular order is necessary so that the sheet is layed out
|
||||
// correctly with and without an enclosing popover
|
||||
preferredContentSize = sheetSize
|
||||
sheetCollectionView.frame = CGRect(origin: CGPoint(x: view.bounds.minX, y: view.bounds.maxY-sheetHeight), size: sheetSize)
|
||||
}
|
||||
|
||||
private func reloadCurrentPreviewHeight(invalidateLayout invalidate: Bool) {
|
||||
if assets.count <= 0 {
|
||||
sheetController.setPreviewHeight(0, invalidateLayout: invalidate)
|
||||
}
|
||||
else if assets.count > 0 && enlargedPreviews {
|
||||
sheetController.setPreviewHeight(maximumPreviewHeight, invalidateLayout: invalidate)
|
||||
}
|
||||
else {
|
||||
sheetController.setPreviewHeight(minimumPreviewHeight, invalidateLayout: invalidate)
|
||||
}
|
||||
}
|
||||
|
||||
private func reloadMaximumPreviewHeight() {
|
||||
let maxHeight: CGFloat = 400
|
||||
let maxImageWidth = sheetController.preferredSheetWidth - 2 * previewCollectionViewInset
|
||||
|
||||
let assetRatios = assets.map { CGSize(width: max($0.pixelHeight, $0.pixelWidth), height: min($0.pixelHeight, $0.pixelWidth)) }
|
||||
.map { $0.height / $0.width }
|
||||
|
||||
let assetHeights = assetRatios.map { $0 * maxImageWidth }
|
||||
.filter { $0 < maxImageWidth && $0 < maxHeight } // Make sure the preview isn't too high eg for squares
|
||||
.sort(>)
|
||||
let assetHeight = ceil(assetHeights.first ?? 0)
|
||||
|
||||
// Just a sanity check, to make sure this doesn't exceed 400 points
|
||||
let scaledHeight = max(min(assetHeight, maxHeight), 200)
|
||||
maximumPreviewHeight = scaledHeight + 2 * previewCollectionViewInset
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
func enlargePreviewsByCenteringToIndexPath(indexPath: NSIndexPath?, completion: (Bool -> ())?) {
|
||||
enlargedPreviews = true
|
||||
previewCollectionView.imagePreviewLayout.invalidationCenteredIndexPath = indexPath
|
||||
reloadCurrentPreviewHeight(invalidateLayout: false)
|
||||
|
||||
view.setNeedsLayout()
|
||||
|
||||
let animationDuration: NSTimeInterval
|
||||
if #available(iOS 9, *) {
|
||||
animationDuration = 0.2
|
||||
}
|
||||
else {
|
||||
animationDuration = 0.3
|
||||
}
|
||||
|
||||
UIView.animateWithDuration(animationDuration, animations: {
|
||||
self.sheetCollectionView.reloadSections(NSIndexSet(index: 0))
|
||||
self.view.layoutIfNeeded()
|
||||
}, completion: completion)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDataSource
|
||||
|
||||
extension ImagePickerSheetController: UICollectionViewDataSource {
|
||||
|
||||
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
|
||||
return assets.count
|
||||
}
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(NSStringFromClass(PreviewCollectionViewCell.self), forIndexPath: indexPath) as! PreviewCollectionViewCell
|
||||
|
||||
let asset = assets[indexPath.section]
|
||||
cell.videoIndicatorView.hidden = asset.mediaType != .Video
|
||||
|
||||
requestImageForAsset(asset) { image in
|
||||
cell.imageView.image = image
|
||||
}
|
||||
|
||||
cell.selected = selectedImageIndices.contains(indexPath.section)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath:
|
||||
NSIndexPath) -> UICollectionReusableView {
|
||||
let view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: NSStringFromClass(PreviewSupplementaryView.self), forIndexPath: indexPath) as! PreviewSupplementaryView
|
||||
view.userInteractionEnabled = false
|
||||
view.buttonInset = UIEdgeInsetsMake(0.0, previewCheckmarkInset, previewCheckmarkInset, 0.0)
|
||||
view.selected = selectedImageIndices.contains(indexPath.section)
|
||||
|
||||
supplementaryViews[indexPath.section] = view
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDelegate
|
||||
|
||||
extension ImagePickerSheetController: UICollectionViewDelegate {
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
|
||||
if let maximumSelection = maximumSelection {
|
||||
if selectedImageIndices.count >= maximumSelection,
|
||||
let previousItemIndex = selectedImageIndices.first {
|
||||
supplementaryViews[previousItemIndex]?.selected = false
|
||||
selectedImageIndices.removeAtIndex(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Just to make sure the image is only selected once
|
||||
selectedImageIndices = selectedImageIndices.filter { $0 != indexPath.section }
|
||||
selectedImageIndices.append(indexPath.section)
|
||||
|
||||
if !enlargedPreviews {
|
||||
enlargePreviewsByCenteringToIndexPath(indexPath) { _ in
|
||||
self.sheetController.reloadActionItems()
|
||||
self.previewCollectionView.imagePreviewLayout.showsSupplementaryViews = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
// scrollToItemAtIndexPath doesn't work reliably
|
||||
if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
|
||||
var contentOffset = CGPointMake(cell.frame.midX - collectionView.frame.width / 2.0, 0.0)
|
||||
contentOffset.x = max(contentOffset.x, -collectionView.contentInset.left)
|
||||
contentOffset.x = min(contentOffset.x, collectionView.contentSize.width - collectionView.frame.width + collectionView.contentInset.right)
|
||||
|
||||
collectionView.setContentOffset(contentOffset, animated: true)
|
||||
}
|
||||
|
||||
sheetController.reloadActionItems()
|
||||
}
|
||||
|
||||
supplementaryViews[indexPath.section]?.selected = true
|
||||
}
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
|
||||
if let index = selectedImageIndices.indexOf(indexPath.section) {
|
||||
selectedImageIndices.removeAtIndex(index)
|
||||
sheetController.reloadActionItems()
|
||||
}
|
||||
|
||||
supplementaryViews[indexPath.section]?.selected = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDelegateFlowLayout
|
||||
|
||||
extension ImagePickerSheetController: UICollectionViewDelegateFlowLayout {
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
|
||||
let asset = assets[indexPath.section]
|
||||
let size = sizeForAsset(asset)
|
||||
|
||||
// Scale down to the current preview height, sizeForAsset returns the original size
|
||||
let currentImagePreviewHeight = sheetController.previewHeight - 2 * previewCollectionViewInset
|
||||
let scale = currentImagePreviewHeight / size.height
|
||||
|
||||
return CGSize(width: size.width * scale, height: currentImagePreviewHeight)
|
||||
}
|
||||
|
||||
public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
||||
let checkmarkWidth = PreviewSupplementaryView.checkmarkImage?.size.width ?? 0
|
||||
return CGSizeMake(checkmarkWidth + 2 * previewCheckmarkInset, sheetController.previewHeight - 2 * previewCollectionViewInset)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UIViewControllerTransitioningDelegate
|
||||
|
||||
extension ImagePickerSheetController: UIViewControllerTransitioningDelegate {
|
||||
|
||||
public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return AnimationController(imagePickerSheetController: self, presenting: true)
|
||||
}
|
||||
|
||||
public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return AnimationController(imagePickerSheetController: self, presenting: false)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "PreviewCollectionViewCell-video.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "PreviewCollectionViewCell-video@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "PreviewCollectionViewCell-video@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 262 B |
|
After Width: | Height: | Size: 413 B |
|
After Width: | Height: | Size: 544 B |
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark-Selected.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark-Selected@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark-Selected@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 713 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "PreviewSupplementaryView-Checkmark@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 629 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,56 @@
|
||||
//
|
||||
// PreviewCollectionView.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 07/09/14.
|
||||
// Copyright (c) 2014 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PreviewCollectionView: UICollectionView {
|
||||
|
||||
var bouncing: Bool {
|
||||
return contentOffset.x < -contentInset.left || contentOffset.x + frame.width > contentSize.width + contentInset.right
|
||||
}
|
||||
|
||||
var imagePreviewLayout: PreviewCollectionViewLayout {
|
||||
return collectionViewLayout as! PreviewCollectionViewLayout
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init() {
|
||||
super.init(frame: CGRectZero, collectionViewLayout: PreviewCollectionViewLayout())
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
panGestureRecognizer.addTarget(self, action: "handlePanGesture:")
|
||||
}
|
||||
|
||||
// MARK: - Panning
|
||||
|
||||
@objc private func handlePanGesture(gestureRecognizer: UIPanGestureRecognizer) {
|
||||
if gestureRecognizer.state == .Ended {
|
||||
let translation = gestureRecognizer.translationInView(self)
|
||||
if translation == CGPoint() {
|
||||
if !bouncing {
|
||||
let possibleIndexPath = indexPathForItemAtPoint(gestureRecognizer.locationInView(self))
|
||||
if let indexPath = possibleIndexPath {
|
||||
selectItemAtIndexPath(indexPath, animated: false, scrollPosition: .None)
|
||||
delegate?.collectionView?(self, didSelectItemAtIndexPath: indexPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
//
|
||||
// PreviewCollectionViewCell.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 06/09/14.
|
||||
// Copyright (c) 2014 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PreviewCollectionViewCell: UICollectionViewCell {
|
||||
|
||||
let imageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
imageView.contentMode = .ScaleAspectFill
|
||||
imageView.clipsToBounds = true
|
||||
|
||||
return imageView
|
||||
}()
|
||||
|
||||
let videoIndicatorView: UIImageView = {
|
||||
let imageView = UIImageView(image: videoImage)
|
||||
imageView.hidden = true
|
||||
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private class var videoImage: UIImage? {
|
||||
let bundle = NSBundle(forClass: ImagePickerSheetController.self)
|
||||
let image = UIImage(named: "PreviewCollectionViewCell-video", inBundle: bundle, compatibleWithTraitCollection: nil)
|
||||
|
||||
return image
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
addSubview(imageView)
|
||||
addSubview(videoIndicatorView)
|
||||
}
|
||||
|
||||
// MARK: - Other Methods
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
imageView.image = nil
|
||||
videoIndicatorView.hidden = true
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
imageView.frame = bounds
|
||||
|
||||
let videoIndicatViewSize = videoIndicatorView.image?.size ?? CGSize()
|
||||
let inset: CGFloat = 4
|
||||
let videoIndicatorViewOrigin = CGPoint(x: bounds.minX + inset, y: bounds.maxY - inset - videoIndicatViewSize.height)
|
||||
videoIndicatorView.frame = CGRect(origin: videoIndicatorViewOrigin, size: videoIndicatViewSize)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
//
|
||||
// PreviewCollectionViewLayout.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 06/09/14.
|
||||
// Copyright (c) 2014 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PreviewCollectionViewLayout: UICollectionViewFlowLayout {
|
||||
|
||||
var invalidationCenteredIndexPath: NSIndexPath?
|
||||
|
||||
var showsSupplementaryViews: Bool = true {
|
||||
didSet {
|
||||
invalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
private var layoutAttributes = [UICollectionViewLayoutAttributes]()
|
||||
private var contentSize = CGSizeZero
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
scrollDirection = .Horizontal
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func prepareLayout() {
|
||||
super.prepareLayout()
|
||||
|
||||
layoutAttributes.removeAll(keepCapacity: false)
|
||||
contentSize = CGSizeZero
|
||||
|
||||
if let collectionView = collectionView,
|
||||
dataSource = collectionView.dataSource,
|
||||
delegate = collectionView.delegate as? UICollectionViewDelegateFlowLayout {
|
||||
var origin = CGPoint(x: sectionInset.left, y: sectionInset.top)
|
||||
let numberOfSections = dataSource.numberOfSectionsInCollectionView?(collectionView) ?? 0
|
||||
|
||||
for s in 0 ..< numberOfSections {
|
||||
let indexPath = NSIndexPath(forItem: 0, inSection: s)
|
||||
let size = delegate.collectionView?(collectionView, layout: self, sizeForItemAtIndexPath: indexPath) ?? CGSizeZero
|
||||
|
||||
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
|
||||
attributes.frame = CGRect(origin: origin, size: size)
|
||||
attributes.zIndex = 0
|
||||
|
||||
layoutAttributes.append(attributes)
|
||||
|
||||
origin.x = attributes.frame.maxX + sectionInset.right
|
||||
}
|
||||
|
||||
contentSize = CGSize(width: origin.x, height: collectionView.frame.height)
|
||||
}
|
||||
}
|
||||
|
||||
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func collectionViewContentSize() -> CGSize {
|
||||
return contentSize
|
||||
}
|
||||
|
||||
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
|
||||
var contentOffset = proposedContentOffset
|
||||
if let indexPath = invalidationCenteredIndexPath {
|
||||
if let collectionView = collectionView {
|
||||
let frame = layoutAttributes[indexPath.section].frame
|
||||
contentOffset.x = frame.midX - collectionView.frame.width / 2.0
|
||||
|
||||
contentOffset.x = max(contentOffset.x, -collectionView.contentInset.left)
|
||||
contentOffset.x = min(contentOffset.x, collectionViewContentSize().width - collectionView.frame.width + collectionView.contentInset.right)
|
||||
}
|
||||
invalidationCenteredIndexPath = nil
|
||||
}
|
||||
|
||||
return super.targetContentOffsetForProposedContentOffset(contentOffset)
|
||||
}
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
return layoutAttributes
|
||||
.filter { CGRectIntersectsRect(rect, $0.frame) }
|
||||
.reduce([UICollectionViewLayoutAttributes]()) { memo, attributes in
|
||||
if let supplementaryAttributes = layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: attributes.indexPath) {
|
||||
return memo + [attributes, supplementaryAttributes]
|
||||
}
|
||||
return memo
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return layoutAttributes[indexPath.section]
|
||||
}
|
||||
|
||||
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
if let collectionView = collectionView,
|
||||
delegate = collectionView.delegate as? UICollectionViewDelegateFlowLayout,
|
||||
itemAttributes = layoutAttributesForItemAtIndexPath(indexPath) {
|
||||
|
||||
let inset = collectionView.contentInset
|
||||
let bounds = collectionView.bounds
|
||||
let contentOffset: CGPoint = {
|
||||
var contentOffset = collectionView.contentOffset
|
||||
contentOffset.x += inset.left
|
||||
contentOffset.y += inset.top
|
||||
|
||||
return contentOffset
|
||||
}()
|
||||
let visibleSize: CGSize = {
|
||||
var size = bounds.size
|
||||
size.width -= (inset.left+inset.right)
|
||||
|
||||
return size
|
||||
}()
|
||||
let visibleFrame = CGRect(origin: contentOffset, size: visibleSize)
|
||||
|
||||
let size = delegate.collectionView?(collectionView, layout: self, referenceSizeForHeaderInSection: indexPath.section) ?? CGSizeZero
|
||||
let originX = max(itemAttributes.frame.minX, min(itemAttributes.frame.maxX - size.width, visibleFrame.maxX - size.width))
|
||||
|
||||
let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath)
|
||||
attributes.zIndex = 1
|
||||
attributes.hidden = !showsSupplementaryViews
|
||||
attributes.frame = CGRect(origin: CGPoint(x: originX, y: itemAttributes.frame.minY), size: size)
|
||||
|
||||
return attributes
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return layoutAttributesForItemAtIndexPath(itemIndexPath)
|
||||
}
|
||||
|
||||
override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return layoutAttributesForItemAtIndexPath(itemIndexPath)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
//
|
||||
// PreviewSupplementaryView.swift
|
||||
// ImagePickerSheet
|
||||
//
|
||||
// Created by Laurin Brandner on 06/09/14.
|
||||
// Copyright (c) 2014 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PreviewSupplementaryView: UICollectionReusableView {
|
||||
|
||||
private let button: UIButton = {
|
||||
let button = UIButton()
|
||||
button.tintColor = .whiteColor()
|
||||
button.userInteractionEnabled = false
|
||||
button.setImage(PreviewSupplementaryView.checkmarkImage, forState: .Normal)
|
||||
button.setImage(PreviewSupplementaryView.selectedCheckmarkImage, forState: .Selected)
|
||||
|
||||
return button
|
||||
}()
|
||||
|
||||
var buttonInset = UIEdgeInsetsZero
|
||||
|
||||
var selected: Bool = false {
|
||||
didSet {
|
||||
button.selected = selected
|
||||
reloadButtonBackgroundColor()
|
||||
}
|
||||
}
|
||||
|
||||
class var checkmarkImage: UIImage? {
|
||||
let bundle = NSBundle(forClass: ImagePickerSheetController.self)
|
||||
let image = UIImage(named: "PreviewSupplementaryView-Checkmark", inBundle: bundle, compatibleWithTraitCollection: nil)
|
||||
|
||||
return image?.imageWithRenderingMode(.AlwaysTemplate)
|
||||
}
|
||||
|
||||
class var selectedCheckmarkImage: UIImage? {
|
||||
let bundle = NSBundle(forClass: ImagePickerSheetController.self)
|
||||
let image = UIImage(named: "PreviewSupplementaryView-Checkmark-Selected", inBundle: bundle, compatibleWithTraitCollection: nil)
|
||||
|
||||
return image?.imageWithRenderingMode(.AlwaysTemplate)
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
addSubview(button)
|
||||
}
|
||||
|
||||
// MARK: - Other Methods
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
selected = false
|
||||
}
|
||||
|
||||
override func tintColorDidChange() {
|
||||
super.tintColorDidChange()
|
||||
|
||||
reloadButtonBackgroundColor()
|
||||
}
|
||||
|
||||
private func reloadButtonBackgroundColor() {
|
||||
button.backgroundColor = (selected) ? tintColor : nil
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
button.sizeToFit()
|
||||
button.frame.origin = CGPointMake(buttonInset.left, CGRectGetHeight(bounds)-CGRectGetHeight(button.frame)-buttonInset.bottom)
|
||||
button.layer.cornerRadius = CGRectGetHeight(button.frame) / 2.0
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
//
|
||||
// SheetActionCollectionViewCell.swift
|
||||
// ImagePickerSheetController
|
||||
//
|
||||
// Created by Laurin Brandner on 26/08/15.
|
||||
// Copyright © 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
let KVOContext = UnsafeMutablePointer<()>()
|
||||
|
||||
class SheetActionCollectionViewCell: SheetCollectionViewCell {
|
||||
|
||||
lazy private(set) var textLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = self.tintColor
|
||||
label.textAlignment = .Center
|
||||
|
||||
self.addSubview(label)
|
||||
|
||||
return label
|
||||
}()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
textLabel.addObserver(self, forKeyPath: "text", options: NSKeyValueObservingOptions(rawValue: 0), context: KVOContext)
|
||||
}
|
||||
|
||||
deinit {
|
||||
textLabel.removeObserver(self, forKeyPath: "text")
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
|
||||
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
|
||||
guard context == KVOContext else {
|
||||
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
|
||||
return
|
||||
}
|
||||
|
||||
accessibilityLabel = textLabel.text
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
override func tintColorDidChange() {
|
||||
super.tintColorDidChange()
|
||||
|
||||
textLabel.textColor = tintColor
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
textLabel.frame = UIEdgeInsetsInsetRect(bounds, backgroundInsets)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
//
|
||||
// SheetCollectionViewCell.swift
|
||||
// ImagePickerSheetController
|
||||
//
|
||||
// Created by Laurin Brandner on 24/08/15.
|
||||
// Copyright © 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum RoundedCorner {
|
||||
case All(CGFloat)
|
||||
case Top(CGFloat)
|
||||
case Bottom(CGFloat)
|
||||
case None
|
||||
}
|
||||
|
||||
class SheetCollectionViewCell: UICollectionViewCell {
|
||||
|
||||
var backgroundInsets = UIEdgeInsets() {
|
||||
didSet {
|
||||
reloadMask()
|
||||
reloadSeparator()
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
var roundedCorners = RoundedCorner.None {
|
||||
didSet {
|
||||
reloadMask()
|
||||
}
|
||||
}
|
||||
|
||||
var separatorVisible = false {
|
||||
didSet {
|
||||
reloadSeparator()
|
||||
}
|
||||
}
|
||||
|
||||
var separatorColor = UIColor.blackColor() {
|
||||
didSet {
|
||||
separatorView?.backgroundColor = separatorColor
|
||||
}
|
||||
}
|
||||
|
||||
var separatorHeight: CGFloat = 1 {
|
||||
didSet {
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
private var separatorView: UIView?
|
||||
|
||||
override var highlighted: Bool {
|
||||
didSet {
|
||||
reloadBackgroundColor()
|
||||
}
|
||||
}
|
||||
|
||||
var highlightedBackgroundColor: UIColor = .clearColor() {
|
||||
didSet {
|
||||
reloadBackgroundColor()
|
||||
}
|
||||
}
|
||||
|
||||
var normalBackgroundColor: UIColor = .clearColor() {
|
||||
didSet {
|
||||
reloadBackgroundColor()
|
||||
}
|
||||
}
|
||||
|
||||
private var needsMasking: Bool {
|
||||
guard backgroundInsets == UIEdgeInsets() else {
|
||||
return true
|
||||
}
|
||||
|
||||
switch roundedCorners {
|
||||
case .None:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initialize()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
layoutMargins = UIEdgeInsets()
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
reloadMask()
|
||||
|
||||
separatorView?.frame = CGRect(x: bounds.minY, y: bounds.maxY - separatorHeight, width: bounds.width, height: separatorHeight)
|
||||
}
|
||||
|
||||
// MARK: - Mask
|
||||
|
||||
private func reloadMask() {
|
||||
if needsMasking && layer.mask == nil {
|
||||
let maskLayer = CAShapeLayer()
|
||||
maskLayer.frame = bounds
|
||||
maskLayer.lineWidth = 0
|
||||
maskLayer.fillColor = UIColor.blackColor().CGColor
|
||||
|
||||
layer.mask = maskLayer
|
||||
}
|
||||
|
||||
let layerMask = layer.mask as? CAShapeLayer
|
||||
layerMask?.frame = bounds
|
||||
layerMask?.path = maskPathWithRect(UIEdgeInsetsInsetRect(bounds, backgroundInsets), roundedCorner: roundedCorners)
|
||||
}
|
||||
|
||||
private func maskPathWithRect(rect: CGRect, roundedCorner: RoundedCorner) -> CGPathRef {
|
||||
let radii: CGFloat
|
||||
let corners: UIRectCorner
|
||||
|
||||
switch roundedCorner {
|
||||
case .All(let value):
|
||||
corners = .AllCorners
|
||||
radii = value
|
||||
case .Top(let value):
|
||||
corners = [.TopLeft, .TopRight]
|
||||
radii = value
|
||||
case .Bottom(let value):
|
||||
corners = [.BottomLeft, .BottomRight]
|
||||
radii = value
|
||||
case .None:
|
||||
return UIBezierPath(rect: rect).CGPath
|
||||
}
|
||||
|
||||
return UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radii, height: radii)).CGPath
|
||||
}
|
||||
|
||||
// MARK: - Separator
|
||||
|
||||
private func reloadSeparator() {
|
||||
if separatorVisible && backgroundInsets.bottom < separatorHeight {
|
||||
if separatorView == nil {
|
||||
let view = UIView()
|
||||
view.backgroundColor = separatorColor
|
||||
|
||||
addSubview(view)
|
||||
separatorView = view
|
||||
}
|
||||
}
|
||||
else {
|
||||
separatorView?.removeFromSuperview()
|
||||
separatorView = nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK - Background
|
||||
|
||||
private func reloadBackgroundColor() {
|
||||
backgroundColor = highlighted ? highlightedBackgroundColor : normalBackgroundColor
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
//
|
||||
// SheetCollectionViewLayout.swift
|
||||
// ImagePickerSheetController
|
||||
//
|
||||
// Created by Laurin Brandner on 26/08/15.
|
||||
// Copyright © 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SheetCollectionViewLayout: UICollectionViewLayout {
|
||||
|
||||
private var layoutAttributes = [[UICollectionViewLayoutAttributes]]()
|
||||
private var invalidatedLayoutAttributes: [[UICollectionViewLayoutAttributes]]?
|
||||
private var contentSize = CGSizeZero
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func prepareLayout() {
|
||||
super.prepareLayout()
|
||||
|
||||
layoutAttributes.removeAll(keepCapacity: false)
|
||||
contentSize = CGSizeZero
|
||||
|
||||
if let collectionView = collectionView,
|
||||
dataSource = collectionView.dataSource,
|
||||
delegate = collectionView.delegate as? UICollectionViewDelegateFlowLayout {
|
||||
let sections = dataSource.numberOfSectionsInCollectionView?(collectionView) ?? 0
|
||||
var origin = CGPoint()
|
||||
|
||||
for section in 0 ..< sections {
|
||||
var sectionAttributes = [UICollectionViewLayoutAttributes]()
|
||||
let items = dataSource.collectionView(collectionView, numberOfItemsInSection: section)
|
||||
let indexPaths = (0 ..< items).map { NSIndexPath(forItem: $0, inSection: section) }
|
||||
|
||||
for indexPath in indexPaths {
|
||||
let size = delegate.collectionView?(collectionView, layout: self, sizeForItemAtIndexPath: indexPath) ?? CGSizeZero
|
||||
|
||||
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
|
||||
attributes.frame = CGRect(origin: origin, size: size)
|
||||
|
||||
sectionAttributes.append(attributes)
|
||||
origin.y = attributes.frame.maxY
|
||||
}
|
||||
|
||||
layoutAttributes.append(sectionAttributes)
|
||||
}
|
||||
|
||||
contentSize = CGSize(width: collectionView.frame.width, height: origin.y)
|
||||
}
|
||||
}
|
||||
|
||||
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func invalidateLayout() {
|
||||
invalidatedLayoutAttributes = layoutAttributes
|
||||
super.invalidateLayout()
|
||||
}
|
||||
|
||||
override func collectionViewContentSize() -> CGSize {
|
||||
return contentSize
|
||||
}
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
return layoutAttributes.reduce([], combine: +)
|
||||
.filter { CGRectIntersectsRect(rect, $0.frame) }
|
||||
}
|
||||
|
||||
private func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath, allAttributes: [[UICollectionViewLayoutAttributes]]) -> UICollectionViewLayoutAttributes? {
|
||||
guard allAttributes.count > indexPath.section && allAttributes[indexPath.section].count > indexPath.item else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return allAttributes[indexPath.section][indexPath.item]
|
||||
}
|
||||
|
||||
private func invalidatedLayoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
guard let invalidatedLayoutAttributes = invalidatedLayoutAttributes else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return layoutAttributesForItemAtIndexPath(indexPath, allAttributes: invalidatedLayoutAttributes)
|
||||
}
|
||||
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return layoutAttributesForItemAtIndexPath(indexPath, allAttributes: layoutAttributes)
|
||||
}
|
||||
|
||||
override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return invalidatedLayoutAttributesForItemAtIndexPath(itemIndexPath) ?? layoutAttributesForItemAtIndexPath(itemIndexPath)
|
||||
}
|
||||
|
||||
override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
return layoutAttributesForItemAtIndexPath(itemIndexPath)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,265 @@
|
||||
//
|
||||
// SheetController.swift
|
||||
// ImagePickerSheetController
|
||||
//
|
||||
// Created by Laurin Brandner on 27/08/15.
|
||||
// Copyright © 2015 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
private let defaultInset: CGFloat = 10
|
||||
|
||||
class SheetController: NSObject {
|
||||
|
||||
private(set) lazy var sheetCollectionView: UICollectionView = {
|
||||
let layout = SheetCollectionViewLayout()
|
||||
let collectionView = UICollectionView(frame: CGRect(), collectionViewLayout: layout)
|
||||
collectionView.dataSource = self
|
||||
collectionView.delegate = self
|
||||
collectionView.accessibilityIdentifier = "ImagePickerSheet"
|
||||
collectionView.backgroundColor = .clearColor()
|
||||
collectionView.alwaysBounceVertical = false
|
||||
collectionView.registerClass(SheetPreviewCollectionViewCell.self, forCellWithReuseIdentifier: NSStringFromClass(SheetPreviewCollectionViewCell.self))
|
||||
collectionView.registerClass(SheetActionCollectionViewCell.self, forCellWithReuseIdentifier: NSStringFromClass(SheetActionCollectionViewCell.self))
|
||||
|
||||
return collectionView
|
||||
}()
|
||||
|
||||
var previewCollectionView: PreviewCollectionView
|
||||
|
||||
private(set) var actions = [ImagePickerAction]()
|
||||
|
||||
var actionHandlingCallback: (() -> ())?
|
||||
|
||||
private(set) var previewHeight: CGFloat = 0
|
||||
var numberOfSelectedImages = 0
|
||||
|
||||
var preferredSheetHeight: CGFloat {
|
||||
return allIndexPaths().map { self.sizeForSheetItemAtIndexPath($0).height }
|
||||
.reduce(0, combine: +)
|
||||
}
|
||||
|
||||
var preferredSheetWidth: CGFloat {
|
||||
guard #available(iOS 9, *) else {
|
||||
return sheetCollectionView.bounds.width
|
||||
}
|
||||
return sheetCollectionView.bounds.width - 2 * defaultInset
|
||||
}
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(previewCollectionView: PreviewCollectionView) {
|
||||
self.previewCollectionView = previewCollectionView
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: - Data Source
|
||||
// These methods are necessary so that no call cycles happen when calculating some design attributes
|
||||
|
||||
private func numberOfSections() -> Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
private func numberOfItemsInSection(section: Int) -> Int {
|
||||
if section == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return actions.count
|
||||
}
|
||||
|
||||
private func allIndexPaths() -> [NSIndexPath] {
|
||||
let s = numberOfSections()
|
||||
return (0 ..< s).map { (self.numberOfItemsInSection($0), $0) }
|
||||
.flatMap { numberOfItems, section in
|
||||
(0 ..< numberOfItems).map { NSIndexPath(forItem: $0, inSection: section) }
|
||||
}
|
||||
}
|
||||
|
||||
private func sizeForSheetItemAtIndexPath(indexPath: NSIndexPath) -> CGSize {
|
||||
let height: CGFloat = {
|
||||
if indexPath.section == 0 {
|
||||
return previewHeight
|
||||
}
|
||||
|
||||
let actionItemHeight: CGFloat
|
||||
|
||||
if #available(iOS 9, *) {
|
||||
actionItemHeight = 57
|
||||
}
|
||||
else {
|
||||
actionItemHeight = 50
|
||||
}
|
||||
|
||||
let insets = attributesForItemAtIndexPath(indexPath).backgroundInsets
|
||||
return actionItemHeight + insets.top + insets.bottom
|
||||
}()
|
||||
|
||||
return CGSize(width: sheetCollectionView.bounds.width, height: height)
|
||||
}
|
||||
|
||||
// MARK: - Design
|
||||
|
||||
private func attributesForItemAtIndexPath(indexPath: NSIndexPath) -> (corners: RoundedCorner, backgroundInsets: UIEdgeInsets) {
|
||||
guard #available(iOS 9, *) else {
|
||||
return (.None, UIEdgeInsets())
|
||||
}
|
||||
|
||||
let cornerRadius: CGFloat = 13
|
||||
let innerInset: CGFloat = 4
|
||||
var indexPaths = allIndexPaths()
|
||||
|
||||
guard indexPaths.first != indexPath else {
|
||||
return (.Top(cornerRadius), UIEdgeInsets(top: 0, left: defaultInset, bottom: 0, right: defaultInset))
|
||||
}
|
||||
|
||||
let cancelIndexPath = actions.indexOf { $0.style == ImagePickerActionStyle.Cancel }
|
||||
.map { NSIndexPath(forItem: $0, inSection: 1) }
|
||||
|
||||
|
||||
if let cancelIndexPath = cancelIndexPath {
|
||||
if cancelIndexPath == indexPath {
|
||||
return (.All(cornerRadius), UIEdgeInsets(top: innerInset, left: defaultInset, bottom: defaultInset, right: defaultInset))
|
||||
}
|
||||
|
||||
indexPaths.removeLast()
|
||||
|
||||
if indexPath == indexPaths.last {
|
||||
return (.Bottom(cornerRadius), UIEdgeInsets(top: 0, left: defaultInset, bottom: innerInset, right: defaultInset))
|
||||
}
|
||||
}
|
||||
else if indexPath == indexPaths.last {
|
||||
return (.Bottom(cornerRadius), UIEdgeInsets(top: 0, left: defaultInset, bottom: defaultInset, right: defaultInset))
|
||||
}
|
||||
|
||||
return (.None, UIEdgeInsets(top: 0, left: defaultInset, bottom: 0, right: defaultInset))
|
||||
}
|
||||
|
||||
private func fontForAction(action: ImagePickerAction) -> UIFont {
|
||||
guard #available(iOS 9, *), action.style == .Cancel else {
|
||||
return UIFont.systemFontOfSize(21)
|
||||
}
|
||||
|
||||
return UIFont.boldSystemFontOfSize(21)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
func reloadActionItems() {
|
||||
sheetCollectionView.reloadSections(NSIndexSet(index: 1))
|
||||
}
|
||||
|
||||
func addAction(action: ImagePickerAction) {
|
||||
if action.style == .Cancel {
|
||||
actions = actions.filter { $0.style != .Cancel }
|
||||
}
|
||||
|
||||
actions.append(action)
|
||||
|
||||
if let index = actions.indexOf({ $0.style == .Cancel }) {
|
||||
let cancelAction = actions.removeAtIndex(index)
|
||||
actions.append(cancelAction)
|
||||
}
|
||||
|
||||
reloadActionItems()
|
||||
}
|
||||
|
||||
private func handleAction(action: ImagePickerAction) {
|
||||
actionHandlingCallback?()
|
||||
action.handle(numberOfSelectedImages)
|
||||
}
|
||||
|
||||
func handleCancelAction() {
|
||||
let cancelAction = actions.filter { $0.style == ImagePickerActionStyle.Cancel }
|
||||
.first
|
||||
|
||||
if let cancelAction = cancelAction {
|
||||
handleAction(cancelAction)
|
||||
}
|
||||
else {
|
||||
actionHandlingCallback?()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
func setPreviewHeight(height: CGFloat, invalidateLayout: Bool) {
|
||||
previewHeight = height
|
||||
if invalidateLayout {
|
||||
sheetCollectionView.collectionViewLayout.invalidateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SheetController: UICollectionViewDataSource {
|
||||
|
||||
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
|
||||
return numberOfSections()
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return numberOfItemsInSection(section)
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
|
||||
let cell: SheetCollectionViewCell
|
||||
|
||||
if indexPath.section == 0 {
|
||||
let previewCell = collectionView.dequeueReusableCellWithReuseIdentifier(NSStringFromClass(SheetPreviewCollectionViewCell.self), forIndexPath: indexPath) as! SheetPreviewCollectionViewCell
|
||||
previewCell.collectionView = previewCollectionView
|
||||
|
||||
cell = previewCell
|
||||
}
|
||||
else {
|
||||
let action = actions[indexPath.item]
|
||||
let actionCell = collectionView.dequeueReusableCellWithReuseIdentifier(NSStringFromClass(SheetActionCollectionViewCell.self), forIndexPath: indexPath) as! SheetActionCollectionViewCell
|
||||
actionCell.textLabel.font = fontForAction(action)
|
||||
actionCell.textLabel.text = numberOfSelectedImages > 0 ? action.secondaryTitle(numberOfSelectedImages) : action.title
|
||||
|
||||
cell = actionCell
|
||||
}
|
||||
|
||||
cell.separatorVisible = (indexPath.section == 1)
|
||||
|
||||
// iOS specific design
|
||||
(cell.roundedCorners, cell.backgroundInsets) = attributesForItemAtIndexPath(indexPath)
|
||||
if #available(iOS 9, *) {
|
||||
cell.normalBackgroundColor = UIColor(white: 0.97, alpha: 1)
|
||||
cell.highlightedBackgroundColor = UIColor(white: 0.92, alpha: 1)
|
||||
cell.separatorColor = UIColor(white: 0.84, alpha: 1)
|
||||
}
|
||||
else {
|
||||
cell.normalBackgroundColor = .whiteColor()
|
||||
cell.highlightedBackgroundColor = UIColor(white: 0.85, alpha: 1)
|
||||
cell.separatorColor = UIColor(white: 0.784, alpha: 1)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SheetController: UICollectionViewDelegate {
|
||||
|
||||
func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
|
||||
return indexPath.section != 0
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
|
||||
collectionView.deselectItemAtIndexPath(indexPath, animated: true)
|
||||
|
||||
handleAction(actions[indexPath.item])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SheetController: UICollectionViewDelegateFlowLayout {
|
||||
|
||||
func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
|
||||
return sizeForSheetItemAtIndexPath(indexPath)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
//
|
||||
// SheetPreviewCollectionViewCell.swift
|
||||
// ImagePickerSheetController
|
||||
//
|
||||
// Created by Laurin Brandner on 06/09/14.
|
||||
// Copyright (c) 2014 Laurin Brandner. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SheetPreviewCollectionViewCell: SheetCollectionViewCell {
|
||||
|
||||
var collectionView: PreviewCollectionView? {
|
||||
willSet {
|
||||
if let collectionView = collectionView {
|
||||
collectionView.removeFromSuperview()
|
||||
}
|
||||
|
||||
if let collectionView = newValue {
|
||||
addSubview(collectionView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Other Methods
|
||||
|
||||
override func prepareForReuse() {
|
||||
collectionView = nil
|
||||
}
|
||||
|
||||
// MARK: - Layout
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
collectionView?.frame = UIEdgeInsetsInsetRect(bounds, backgroundInsets)
|
||||
}
|
||||
|
||||
}
|
||||
21
ios/Pods/ImagePickerSheetController/LICENSE
generated
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Laurin Brandner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
56
ios/Pods/ImagePickerSheetController/README.md
generated
Normal file
@ -0,0 +1,56 @@
|
||||
# ImagePickerSheetController
|
||||
|
||||
[](https://twitter.com/larcus94)
|
||||
[](https://github.com/larcus94/ImagePickerSheetController/blob/master/LICENSE)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
|
||||
## About
|
||||
ImagePickerSheetController is a component that replicates the custom photo action sheet in iMessage. It's very similar to UIAlertController which makes its usage simple and concise.
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
`ImagePickerSheetController` is similar to `UIAlertController` in its usage.
|
||||
|
||||
### Example
|
||||
|
||||
```swift
|
||||
let controller = ImagePickerSheetController(mediaType: .ImageAndVideo)
|
||||
controller.addAction(ImagePickerAction(title: NSLocalizedString("Take Photo Or Video", comment: "Action Title"), secondaryTitle: NSLocalizedString("Add comment", comment: "Action Title"), handler: { _ in
|
||||
presentImagePickerController(.Camera)
|
||||
}, secondaryHandler: { _, numberOfPhotos in
|
||||
println("Comment \(numberOfPhotos) photos")
|
||||
}))
|
||||
controller.addAction(ImagePickerAction(title: NSLocalizedString("Photo Library", comment: "Action Title"), secondaryTitle: { NSString.localizedStringWithFormat(NSLocalizedString("ImagePickerSheet.button1.Send %lu Photo", comment: "Action Title"), $0) as String}, handler: { _ in
|
||||
presentImagePickerController(.PhotoLibrary)
|
||||
}, secondaryHandler: { _, numberOfPhotos in
|
||||
println("Send \(controller.selectedImageAssets)")
|
||||
}))
|
||||
controller.addAction(ImagePickerAction(title: NSLocalizedString("Cancel", comment: "Action Title"), style: .Cancel, handler: { _ in
|
||||
println("Cancelled")
|
||||
}))
|
||||
|
||||
presentViewController(controller, animated: true, completion: nil)
|
||||
```
|
||||
It's recommended to use [stringsdict](https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/StringsdictFileFormat/StringsdictFileFormat.html) to easily translate plural forms in any language.
|
||||
|
||||
## Installation
|
||||
|
||||
### CocoaPods
|
||||
```ruby
|
||||
pod "ImagePickerSheetController", "~> 0.9.1"
|
||||
```
|
||||
|
||||
###Carthage
|
||||
```objc
|
||||
github "larcus94/ImagePickerSheetController" ~> 0.9.1
|
||||
```
|
||||
|
||||
## Requirements
|
||||
ImagePickerSheetController is written in Swift and links against `Photos.framework`. It therefore requires iOS 8 or later.
|
||||
|
||||
## Author
|
||||
I'm Laurin Brandner, I'm on [Twitter](https://twitter.com/larcus94).
|
||||
|
||||
## License
|
||||
ImagePickerSheetController is licensed under the [MIT License](http://opensource.org/licenses/mit-license.php).
|
||||
10
ios/Pods/Manifest.lock
generated
Normal file
@ -0,0 +1,10 @@
|
||||
PODS:
|
||||
- ImagePickerSheetController (0.9.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- ImagePickerSheetController
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
ImagePickerSheetController: 3c58c9fee6dcf36485222358a021f6b734f997ba
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
573
ios/Pods/Pods.xcodeproj/project.pbxproj
generated
Normal file
@ -0,0 +1,573 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
079630E2D4FDD18DA1148E24A6D9F48C /* ImagePickerAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DBA2152DC4141AF0EE54E2DB10210B5 /* ImagePickerAction.swift */; };
|
||||
180378212E28F7A112A87A43DF6E5F7F /* PreviewCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67719E721B448F6065B50621081684A /* PreviewCollectionView.swift */; };
|
||||
3343C7EF8FC7413A0A907F6FC5C78C74 /* SheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A35A3834BF674B5F1CDB72D9D646658 /* SheetController.swift */; };
|
||||
363134533B7518E26FEB125E29D3BDF5 /* PreviewCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CE6E7CD62AF49861EC3F12442386C0 /* PreviewCollectionViewCell.swift */; };
|
||||
37A5494E25A4BEB49274FD8644A6D194 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E36762FF8E4A4E113EEC970F71E699C /* Foundation.framework */; };
|
||||
3BEBBF1BC29E28E275612602AD2CBC58 /* Pods-ReactNativeCameraKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F3AC07D2E4446CA38B0AFB55935D506 /* Pods-ReactNativeCameraKit-dummy.m */; };
|
||||
5A97CB0EA725BF0EA48A2B3CBF199887 /* ImagePickerSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C525DEF5158DF542A9FAB0874C83A06E /* ImagePickerSheetController.swift */; };
|
||||
5D0DE2F60AE2806F484AC6D0F53362A5 /* AnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2D98780222413EDBBD45C7302EC0BA8 /* AnimationController.swift */; };
|
||||
65DDC4906B56C3C19A03B2EB4257435F /* ImagePickerSheetController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3134E79C0CA7BE51D6DD42575AC4BD78 /* ImagePickerSheetController-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
6700755A206C8136A97B20B9D2FA788C /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 697E2FB9C7768EDEA1457A96EDB78BE9 /* Photos.framework */; };
|
||||
6FFF9F6BAB7E459AFFBE5C6B4343372C /* SheetActionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFFC468480F371982DE65A908A41DA21 /* SheetActionCollectionViewCell.swift */; };
|
||||
884AE123CAC9A5491C23AE729FE4832D /* SheetCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06F339EAACD2E9ED6A6119E816DC3AA /* SheetCollectionViewLayout.swift */; };
|
||||
9180B8BA812802D78F860175B02387FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2C06E2463508844773E3E096A35A47C /* Images.xcassets */; };
|
||||
B8912CE08C66BD2B6189745EDB35F33F /* PreviewCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C00EDF48AC63BAA768D0A0B6E20C31B /* PreviewCollectionViewLayout.swift */; };
|
||||
CD78C10DADDEC6B5E39D47DFE8975B48 /* Pods-ReactNativeCameraKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 66B38237FA9EF751ED77E239C733829D /* Pods-ReactNativeCameraKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D1A2E5C864D0CB49A2E760B345A9852F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E36762FF8E4A4E113EEC970F71E699C /* Foundation.framework */; };
|
||||
E7B7BAB2FE1730965D067CE994FB7EC2 /* ImagePickerSheetController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FD0EAA78B4A44CC82E24ED80A813BFDB /* ImagePickerSheetController-dummy.m */; };
|
||||
E8129D7EC7434F22247C35916CBAD0B8 /* PreviewSupplementaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C844465AE2EA77CFF17AA3699FFB79CD /* PreviewSupplementaryView.swift */; };
|
||||
EE75E9914DE58A76A5460938813EE4DC /* SheetCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 990E4D7FD59799C10E85A6487106B18B /* SheetCollectionViewCell.swift */; };
|
||||
F2E2DE1EC6D5DA0477EA29AF543017A2 /* SheetPreviewCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBE83F6A85A4DEAE74B5AD71A974CAE /* SheetPreviewCollectionViewCell.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
DDFBF28D1A8D92742997C008E7B80ED5 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2AAAB9973850C35994DC04473435E1A3;
|
||||
remoteInfo = ImagePickerSheetController;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
03E2CDD46BB9E1A4A66D0550179FDC2C /* Pods-ReactNativeCameraKit-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ReactNativeCameraKit-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
0F3AC07D2E4446CA38B0AFB55935D506 /* Pods-ReactNativeCameraKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ReactNativeCameraKit-dummy.m"; sourceTree = "<group>"; };
|
||||
12CE2841A34BEB5906032E3980F43037 /* ImagePickerSheetController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ImagePickerSheetController-prefix.pch"; sourceTree = "<group>"; };
|
||||
1E0275907FE8E85889145D3B97263935 /* ImagePickerSheetController.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ImagePickerSheetController.xcconfig; sourceTree = "<group>"; };
|
||||
2C00EDF48AC63BAA768D0A0B6E20C31B /* PreviewCollectionViewLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PreviewCollectionViewLayout.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/Preview/PreviewCollectionViewLayout.swift; sourceTree = "<group>"; };
|
||||
3134E79C0CA7BE51D6DD42575AC4BD78 /* ImagePickerSheetController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ImagePickerSheetController-umbrella.h"; sourceTree = "<group>"; };
|
||||
3CF582E27F74A69C6F871ED64816F6DE /* Pods-ReactNativeCameraKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ReactNativeCameraKit.release.xcconfig"; sourceTree = "<group>"; };
|
||||
4A35A3834BF674B5F1CDB72D9D646658 /* SheetController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SheetController.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/SheetController.swift; sourceTree = "<group>"; };
|
||||
4EBE83F6A85A4DEAE74B5AD71A974CAE /* SheetPreviewCollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SheetPreviewCollectionViewCell.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/SheetPreviewCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
66B38237FA9EF751ED77E239C733829D /* Pods-ReactNativeCameraKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ReactNativeCameraKit-umbrella.h"; sourceTree = "<group>"; };
|
||||
68DF5BE345BF4A20C242226D8BDFC520 /* Pods-ReactNativeCameraKit-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ReactNativeCameraKit-frameworks.sh"; sourceTree = "<group>"; };
|
||||
697E2FB9C7768EDEA1457A96EDB78BE9 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; };
|
||||
75CE6E7CD62AF49861EC3F12442386C0 /* PreviewCollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PreviewCollectionViewCell.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/Preview/PreviewCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
7AA7C40F5CD7AC6BF35E1B0065DA72C5 /* Pods-ReactNativeCameraKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-ReactNativeCameraKit.modulemap"; sourceTree = "<group>"; };
|
||||
9480CFCA0F9FB4526A047ED920A554BC /* Pods-ReactNativeCameraKit-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ReactNativeCameraKit-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
990E4D7FD59799C10E85A6487106B18B /* SheetCollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SheetCollectionViewCell.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/SheetCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
9DBA2152DC4141AF0EE54E2DB10210B5 /* ImagePickerAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePickerAction.swift; path = ImagePickerSheetController/ImagePickerSheetController/ImagePickerAction.swift; sourceTree = "<group>"; };
|
||||
9E36762FF8E4A4E113EEC970F71E699C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A2D98780222413EDBBD45C7302EC0BA8 /* AnimationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimationController.swift; path = ImagePickerSheetController/ImagePickerSheetController/AnimationController.swift; sourceTree = "<group>"; };
|
||||
AE1EF0EC94DA87361C0406DA6AC248C3 /* ImagePickerSheetController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImagePickerSheetController.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B67719E721B448F6065B50621081684A /* PreviewCollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PreviewCollectionView.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/Preview/PreviewCollectionView.swift; sourceTree = "<group>"; };
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
BA9C090317F3F76F40B0CACF691929EE /* Pods-ReactNativeCameraKit-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ReactNativeCameraKit-resources.sh"; sourceTree = "<group>"; };
|
||||
C525DEF5158DF542A9FAB0874C83A06E /* ImagePickerSheetController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePickerSheetController.swift; path = ImagePickerSheetController/ImagePickerSheetController/ImagePickerSheetController.swift; sourceTree = "<group>"; };
|
||||
C844465AE2EA77CFF17AA3699FFB79CD /* PreviewSupplementaryView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PreviewSupplementaryView.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/Preview/PreviewSupplementaryView.swift; sourceTree = "<group>"; };
|
||||
CAE48460691A7F16DC3E2A8158DA8C1C /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CD097932506E41F66E1BB103B2080A8D /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CDDDD47987996CE6E4F88ACE58031BA9 /* ImagePickerSheetController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = ImagePickerSheetController.modulemap; sourceTree = "<group>"; };
|
||||
E06F339EAACD2E9ED6A6119E816DC3AA /* SheetCollectionViewLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SheetCollectionViewLayout.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/SheetCollectionViewLayout.swift; sourceTree = "<group>"; };
|
||||
EEF467F3FE90185318D7CC581BB160FA /* Pods-ReactNativeCameraKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ReactNativeCameraKit.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
F2C06E2463508844773E3E096A35A47C /* Images.xcassets */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ImagePickerSheetController/ImagePickerSheetController/Images.xcassets; sourceTree = "<group>"; };
|
||||
F831E4A5EFAFD16B864480C9C0F8E1E9 /* Pods_ReactNativeCameraKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReactNativeCameraKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FD0EAA78B4A44CC82E24ED80A813BFDB /* ImagePickerSheetController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ImagePickerSheetController-dummy.m"; sourceTree = "<group>"; };
|
||||
FFFC468480F371982DE65A908A41DA21 /* SheetActionCollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SheetActionCollectionViewCell.swift; path = ImagePickerSheetController/ImagePickerSheetController/Sheet/SheetActionCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
185CDE137F7E9E23F1CE9B518D47E7FB /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D1A2E5C864D0CB49A2E760B345A9852F /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B00AEE85F1051CEEC27A8D13F638E23C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
37A5494E25A4BEB49274FD8644A6D194 /* Foundation.framework in Frameworks */,
|
||||
6700755A206C8136A97B20B9D2FA788C /* Photos.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CF60819FDD9A8A1FDDBE8C01CFDB526F /* iOS */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
755C1EE9F7841B918D05512036D6F60D /* Targets Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CB688DDE44D693E9312BCCFEF49508F5 /* Pods-ReactNativeCameraKit */,
|
||||
);
|
||||
name = "Targets Support Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DB346D0F39D3F0E887471402A8071AB = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */,
|
||||
433CD3331B6C3787F473C941B61FC68F /* Frameworks */,
|
||||
EF0BF5064E61294AD74BCC8C19C17E70 /* Pods */,
|
||||
AF7A76083693DFBE6F6696812B7370A6 /* Products */,
|
||||
755C1EE9F7841B918D05512036D6F60D /* Targets Support Files */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9531269308E2BE6B671DDE9564BFE996 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F2C06E2463508844773E3E096A35A47C /* Images.xcassets */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AF7A76083693DFBE6F6696812B7370A6 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AE1EF0EC94DA87361C0406DA6AC248C3 /* ImagePickerSheetController.framework */,
|
||||
F831E4A5EFAFD16B864480C9C0F8E1E9 /* Pods_ReactNativeCameraKit.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CB688DDE44D693E9312BCCFEF49508F5 /* Pods-ReactNativeCameraKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD097932506E41F66E1BB103B2080A8D /* Info.plist */,
|
||||
7AA7C40F5CD7AC6BF35E1B0065DA72C5 /* Pods-ReactNativeCameraKit.modulemap */,
|
||||
03E2CDD46BB9E1A4A66D0550179FDC2C /* Pods-ReactNativeCameraKit-acknowledgements.markdown */,
|
||||
9480CFCA0F9FB4526A047ED920A554BC /* Pods-ReactNativeCameraKit-acknowledgements.plist */,
|
||||
0F3AC07D2E4446CA38B0AFB55935D506 /* Pods-ReactNativeCameraKit-dummy.m */,
|
||||
68DF5BE345BF4A20C242226D8BDFC520 /* Pods-ReactNativeCameraKit-frameworks.sh */,
|
||||
BA9C090317F3F76F40B0CACF691929EE /* Pods-ReactNativeCameraKit-resources.sh */,
|
||||
66B38237FA9EF751ED77E239C733829D /* Pods-ReactNativeCameraKit-umbrella.h */,
|
||||
EEF467F3FE90185318D7CC581BB160FA /* Pods-ReactNativeCameraKit.debug.xcconfig */,
|
||||
3CF582E27F74A69C6F871ED64816F6DE /* Pods-ReactNativeCameraKit.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-ReactNativeCameraKit";
|
||||
path = "Target Support Files/Pods-ReactNativeCameraKit";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CF60819FDD9A8A1FDDBE8C01CFDB526F /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E36762FF8E4A4E113EEC970F71E699C /* Foundation.framework */,
|
||||
697E2FB9C7768EDEA1457A96EDB78BE9 /* Photos.framework */,
|
||||
);
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D50700D5541FD756EDCE4782B04829C5 /* ImagePickerSheetController */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A2D98780222413EDBBD45C7302EC0BA8 /* AnimationController.swift */,
|
||||
9DBA2152DC4141AF0EE54E2DB10210B5 /* ImagePickerAction.swift */,
|
||||
C525DEF5158DF542A9FAB0874C83A06E /* ImagePickerSheetController.swift */,
|
||||
B67719E721B448F6065B50621081684A /* PreviewCollectionView.swift */,
|
||||
75CE6E7CD62AF49861EC3F12442386C0 /* PreviewCollectionViewCell.swift */,
|
||||
2C00EDF48AC63BAA768D0A0B6E20C31B /* PreviewCollectionViewLayout.swift */,
|
||||
C844465AE2EA77CFF17AA3699FFB79CD /* PreviewSupplementaryView.swift */,
|
||||
FFFC468480F371982DE65A908A41DA21 /* SheetActionCollectionViewCell.swift */,
|
||||
990E4D7FD59799C10E85A6487106B18B /* SheetCollectionViewCell.swift */,
|
||||
E06F339EAACD2E9ED6A6119E816DC3AA /* SheetCollectionViewLayout.swift */,
|
||||
4A35A3834BF674B5F1CDB72D9D646658 /* SheetController.swift */,
|
||||
4EBE83F6A85A4DEAE74B5AD71A974CAE /* SheetPreviewCollectionViewCell.swift */,
|
||||
9531269308E2BE6B671DDE9564BFE996 /* Resources */,
|
||||
F45EBA593415998AE41C5B6B2974419A /* Support Files */,
|
||||
);
|
||||
path = ImagePickerSheetController;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EF0BF5064E61294AD74BCC8C19C17E70 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D50700D5541FD756EDCE4782B04829C5 /* ImagePickerSheetController */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F45EBA593415998AE41C5B6B2974419A /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CDDDD47987996CE6E4F88ACE58031BA9 /* ImagePickerSheetController.modulemap */,
|
||||
1E0275907FE8E85889145D3B97263935 /* ImagePickerSheetController.xcconfig */,
|
||||
FD0EAA78B4A44CC82E24ED80A813BFDB /* ImagePickerSheetController-dummy.m */,
|
||||
12CE2841A34BEB5906032E3980F43037 /* ImagePickerSheetController-prefix.pch */,
|
||||
3134E79C0CA7BE51D6DD42575AC4BD78 /* ImagePickerSheetController-umbrella.h */,
|
||||
CAE48460691A7F16DC3E2A8158DA8C1C /* Info.plist */,
|
||||
);
|
||||
name = "Support Files";
|
||||
path = "../Target Support Files/ImagePickerSheetController";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
5E0B6160A5A178C00ED9CD79C7BC1CD4 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
65DDC4906B56C3C19A03B2EB4257435F /* ImagePickerSheetController-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9C4B1C2AFE3CA38462A9D283ED2D3A28 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CD78C10DADDEC6B5E39D47DFE8975B48 /* Pods-ReactNativeCameraKit-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
09C554F08A60A36AC2B390B2B0F706AF /* Pods-ReactNativeCameraKit */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E15230A1C51A9843BED269A28D1C8D93 /* Build configuration list for PBXNativeTarget "Pods-ReactNativeCameraKit" */;
|
||||
buildPhases = (
|
||||
DF3887247B7FA5F2B9570A1532E8825A /* Sources */,
|
||||
185CDE137F7E9E23F1CE9B518D47E7FB /* Frameworks */,
|
||||
9C4B1C2AFE3CA38462A9D283ED2D3A28 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
BBCF5D5AD9006C324C0CCA9B69B2FA27 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-ReactNativeCameraKit";
|
||||
productName = "Pods-ReactNativeCameraKit";
|
||||
productReference = F831E4A5EFAFD16B864480C9C0F8E1E9 /* Pods_ReactNativeCameraKit.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
2AAAB9973850C35994DC04473435E1A3 /* ImagePickerSheetController */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 5580ECE611FF697E03DD45816B0B5871 /* Build configuration list for PBXNativeTarget "ImagePickerSheetController" */;
|
||||
buildPhases = (
|
||||
D6EFA694F15215890B83641196A85498 /* Sources */,
|
||||
B00AEE85F1051CEEC27A8D13F638E23C /* Frameworks */,
|
||||
407B72996CFC6B907B5482F8FFBB4443 /* Resources */,
|
||||
5E0B6160A5A178C00ED9CD79C7BC1CD4 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ImagePickerSheetController;
|
||||
productName = ImagePickerSheetController;
|
||||
productReference = AE1EF0EC94DA87361C0406DA6AC248C3 /* ImagePickerSheetController.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
D41D8CD98F00B204E9800998ECF8427E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0700;
|
||||
};
|
||||
buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 7DB346D0F39D3F0E887471402A8071AB;
|
||||
productRefGroup = AF7A76083693DFBE6F6696812B7370A6 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
2AAAB9973850C35994DC04473435E1A3 /* ImagePickerSheetController */,
|
||||
09C554F08A60A36AC2B390B2B0F706AF /* Pods-ReactNativeCameraKit */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
407B72996CFC6B907B5482F8FFBB4443 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9180B8BA812802D78F860175B02387FF /* Images.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
D6EFA694F15215890B83641196A85498 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5D0DE2F60AE2806F484AC6D0F53362A5 /* AnimationController.swift in Sources */,
|
||||
079630E2D4FDD18DA1148E24A6D9F48C /* ImagePickerAction.swift in Sources */,
|
||||
E7B7BAB2FE1730965D067CE994FB7EC2 /* ImagePickerSheetController-dummy.m in Sources */,
|
||||
5A97CB0EA725BF0EA48A2B3CBF199887 /* ImagePickerSheetController.swift in Sources */,
|
||||
180378212E28F7A112A87A43DF6E5F7F /* PreviewCollectionView.swift in Sources */,
|
||||
363134533B7518E26FEB125E29D3BDF5 /* PreviewCollectionViewCell.swift in Sources */,
|
||||
B8912CE08C66BD2B6189745EDB35F33F /* PreviewCollectionViewLayout.swift in Sources */,
|
||||
E8129D7EC7434F22247C35916CBAD0B8 /* PreviewSupplementaryView.swift in Sources */,
|
||||
6FFF9F6BAB7E459AFFBE5C6B4343372C /* SheetActionCollectionViewCell.swift in Sources */,
|
||||
EE75E9914DE58A76A5460938813EE4DC /* SheetCollectionViewCell.swift in Sources */,
|
||||
884AE123CAC9A5491C23AE729FE4832D /* SheetCollectionViewLayout.swift in Sources */,
|
||||
3343C7EF8FC7413A0A907F6FC5C78C74 /* SheetController.swift in Sources */,
|
||||
F2E2DE1EC6D5DA0477EA29AF543017A2 /* SheetPreviewCollectionViewCell.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DF3887247B7FA5F2B9570A1532E8825A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3BEBBF1BC29E28E275612602AD2CBC58 /* Pods-ReactNativeCameraKit-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
BBCF5D5AD9006C324C0CCA9B69B2FA27 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = ImagePickerSheetController;
|
||||
target = 2AAAB9973850C35994DC04473435E1A3 /* ImagePickerSheetController */;
|
||||
targetProxy = DDFBF28D1A8D92742997C008E7B80ED5 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
8861DB452DF06013FA92AD2062B9FB19 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3CF582E27F74A69C6F871ED64816F6DE /* Pods-ReactNativeCameraKit.release.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-ReactNativeCameraKit/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MACH_O_TYPE = staticlib;
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_ReactNativeCameraKit;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94547D0F14ABE31A6C5C38D3A12D793D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1E0275907FE8E85889145D3B97263935 /* ImagePickerSheetController.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_PREFIX_HEADER = "Target Support Files/ImagePickerSheetController/ImagePickerSheetController-prefix.pch";
|
||||
INFOPLIST_FILE = "Target Support Files/ImagePickerSheetController/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/ImagePickerSheetController/ImagePickerSheetController.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = ImagePickerSheetController;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
CA05C723B40F3F3B1C4184E935ED6B83 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1E0275907FE8E85889145D3B97263935 /* ImagePickerSheetController.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_PREFIX_HEADER = "Target Support Files/ImagePickerSheetController/ImagePickerSheetController-prefix.pch";
|
||||
INFOPLIST_FILE = "Target Support Files/ImagePickerSheetController/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/ImagePickerSheetController/ImagePickerSheetController.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_NAME = ImagePickerSheetController;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F21EF67338BE2D05560FDBD505F6847C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = EEF467F3FE90185318D7CC581BB160FA /* Pods-ReactNativeCameraKit.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-ReactNativeCameraKit/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MACH_O_TYPE = staticlib;
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_ReactNativeCameraKit;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FB45FFD90572718D82AB9092B750F0CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */,
|
||||
FB45FFD90572718D82AB9092B750F0CA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
5580ECE611FF697E03DD45816B0B5871 /* Build configuration list for PBXNativeTarget "ImagePickerSheetController" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
CA05C723B40F3F3B1C4184E935ED6B83 /* Debug */,
|
||||
94547D0F14ABE31A6C5C38D3A12D793D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E15230A1C51A9843BED269A28D1C8D93 /* Build configuration list for PBXNativeTarget "Pods-ReactNativeCameraKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
F21EF67338BE2D05560FDBD505F6847C /* Debug */,
|
||||
8861DB452DF06013FA92AD2062B9FB19 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
}
|
||||
5
ios/Pods/Target Support Files/ImagePickerSheetController/ImagePickerSheetController-dummy.m
generated
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_ImagePickerSheetController : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_ImagePickerSheetController
|
||||
@end
|
||||
4
ios/Pods/Target Support Files/ImagePickerSheetController/ImagePickerSheetController-prefix.pch
generated
Normal file
@ -0,0 +1,4 @@
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
6
ios/Pods/Target Support Files/ImagePickerSheetController/ImagePickerSheetController-umbrella.h
generated
Normal file
@ -0,0 +1,6 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double ImagePickerSheetControllerVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char ImagePickerSheetControllerVersionString[];
|
||||
|
||||
6
ios/Pods/Target Support Files/ImagePickerSheetController/ImagePickerSheetController.modulemap
generated
Normal file
@ -0,0 +1,6 @@
|
||||
framework module ImagePickerSheetController {
|
||||
umbrella header "ImagePickerSheetController-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
6
ios/Pods/Target Support Files/ImagePickerSheetController/ImagePickerSheetController.xcconfig
generated
Normal file
@ -0,0 +1,6 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ImagePickerSheetController" "${PODS_ROOT}/Headers/Public"
|
||||
OTHER_LDFLAGS = -framework "Photos"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
SKIP_INSTALL = YES
|
||||
26
ios/Pods/Target Support Files/ImagePickerSheetController/Info.plist
generated
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.9.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
26
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Info.plist
generated
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,28 @@
|
||||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## ImagePickerSheetController
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Laurin Brandner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Generated by CocoaPods - http://cocoapods.org
|
||||
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Laurin Brandner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
</string>
|
||||
<key>Title</key>
|
||||
<string>ImagePickerSheetController</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - http://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
5
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-dummy.m
generated
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_ReactNativeCameraKit : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_ReactNativeCameraKit
|
||||
@end
|
||||
91
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-frameworks.sh
generated
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
# use filter instead of exclude so missing patterns dont' throw errors
|
||||
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identitiy
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\""
|
||||
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current file
|
||||
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
|
||||
stripped=""
|
||||
for arch in $archs; do
|
||||
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "Pods-ReactNativeCameraKit/ImagePickerSheetController.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework "Pods-ReactNativeCameraKit/ImagePickerSheetController.framework"
|
||||
fi
|
||||
95
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-resources.sh
generated
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||
> "$RESOURCES_TO_COPY"
|
||||
|
||||
XCASSET_FILES=()
|
||||
|
||||
realpath() {
|
||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
||||
FILENAME="${1##*/}"
|
||||
echo "$DIRECTORY/$FILENAME"
|
||||
}
|
||||
|
||||
install_resource()
|
||||
{
|
||||
case $1 in
|
||||
*.storyboard)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.xib)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.framework)
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
;;
|
||||
*.xcdatamodel)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
|
||||
;;
|
||||
*.xcdatamodeld)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
|
||||
;;
|
||||
*.xcmappingmodel)
|
||||
echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
|
||||
xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1")
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
/*)
|
||||
echo "$1"
|
||||
echo "$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
*)
|
||||
echo "${PODS_ROOT}/$1"
|
||||
echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
rm -f "$RESOURCES_TO_COPY"
|
||||
|
||||
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
|
||||
then
|
||||
case "${TARGETED_DEVICE_FAMILY}" in
|
||||
1,2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||
;;
|
||||
1)
|
||||
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||
;;
|
||||
2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||
;;
|
||||
*)
|
||||
TARGET_DEVICE_ARGS="--target-device mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
6
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-umbrella.h
generated
Normal file
@ -0,0 +1,6 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double Pods_ReactNativeCameraKitVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char Pods_ReactNativeCameraKitVersionString[];
|
||||
|
||||
8
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.debug.xcconfig
generated
Normal file
@ -0,0 +1,8 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/ImagePickerSheetController.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "ImagePickerSheetController"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-ReactNativeCameraKit
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
6
ios/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.modulemap
generated
Normal file
@ -0,0 +1,6 @@
|
||||
framework module Pods_ReactNativeCameraKit {
|
||||
umbrella header "Pods-ReactNativeCameraKit-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/ImagePickerSheetController.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "ImagePickerSheetController"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-ReactNativeCameraKit
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
4
ios/ReactNativeCameraKit-Bridging-Header.h
Normal file
@ -0,0 +1,4 @@
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
|
||||
16
ios/ReactNativeCameraKit.m
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// RCTCameraKitManager.m
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface RCT_EXTERN_MODULE(ReactNativeCameraKit, NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(presentPhotoPicker:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback)
|
||||
|
||||
@end
|
||||
170
ios/ReactNativeCameraKit.swift
Normal file
@ -0,0 +1,170 @@
|
||||
//
|
||||
// RCTCameraKitManager.swift
|
||||
// ReactNativeCameraKit
|
||||
//
|
||||
// Created by Natalia Grankina on 4/13/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MobileCoreServices
|
||||
import Photos
|
||||
import ImagePickerSheetController
|
||||
|
||||
@objc(ReactNativeCameraKit)
|
||||
|
||||
class ReactNativeCameraKit: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CameraViewControllerDelegate {
|
||||
var defaultOptions: [String: AnyObject]
|
||||
var callback: RCTResponseSenderBlock? = nil
|
||||
|
||||
override init() {
|
||||
defaultOptions = [String: AnyObject]()
|
||||
defaultOptions["takePhotoActionTitle"] = "Take a Photo"
|
||||
defaultOptions["pickPhotoActionTitle"] = "Gallery"
|
||||
defaultOptions["cancelActionTitle"] = "Cancel"
|
||||
defaultOptions["sendSelectedPhotosTitle"] = "Send %lu Photo"
|
||||
defaultOptions["aspectRatioInfoMessage"] = "Your images look best with 16:9 ratio"
|
||||
defaultOptions["aspectRatios"] = ["16:9", "1:1", "4:3", "3:2", "2:3", "3:4", "9:16"]
|
||||
defaultOptions["collectionName"] = "eCom"
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
func presentPhotoPicker(options: [String: AnyObject], callback: RCTResponseSenderBlock) -> Void {
|
||||
var computedOptions = [String: AnyObject]()
|
||||
self.callback = callback
|
||||
|
||||
for (key, value) in defaultOptions {
|
||||
computedOptions[key] = value
|
||||
}
|
||||
for (key, value) in options {
|
||||
computedOptions[key] = value;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), {
|
||||
let controller = ImagePickerSheetController(mediaType: .Image)
|
||||
|
||||
let takePhotoAction = ImagePickerAction(
|
||||
title: computedOptions["takePhotoActionTitle"] as! String,
|
||||
handler: { _ in
|
||||
self.launchCamera(["aspectRatioInfoMessage": computedOptions["aspectRatioInfoMessage"]!, "aspectRatios": computedOptions["aspectRatios"]!, "collectionName": computedOptions["collectionName"]!])
|
||||
}
|
||||
)
|
||||
controller.addAction(takePhotoAction)
|
||||
|
||||
let pickPhotoAction = ImagePickerAction(
|
||||
title: computedOptions["pickPhotoActionTitle"] as! String,
|
||||
secondaryTitle: { NSString.localizedStringWithFormat(computedOptions["sendSelectedPhotosTitle"] as! String, $0) as String},
|
||||
handler: { _ in
|
||||
self.presentImagePickerController(.PhotoLibrary)
|
||||
},
|
||||
secondaryHandler: { _, numberOfPhotos in
|
||||
var selectedImages = [String]()
|
||||
for imageAsset in controller.selectedImageAssets {
|
||||
PHImageManager.defaultManager().requestImageDataForAsset(imageAsset,
|
||||
options: PHImageRequestOptions(),
|
||||
resultHandler: { (imageData, _, orientation, info) -> Void in
|
||||
selectedImages.append(imageData!.base64EncodedStringWithOptions([]))
|
||||
if (selectedImages.count == controller.selectedImageAssets.count) {
|
||||
self.executeCallback(["images": selectedImages])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
controller.addAction(pickPhotoAction)
|
||||
|
||||
let cancelAction = ImagePickerAction(
|
||||
title: computedOptions["cancelActionTitle"] as! String,
|
||||
style: .Cancel,
|
||||
handler: { _ in
|
||||
self.notifyAboutCancel()
|
||||
}
|
||||
)
|
||||
controller.addAction(cancelAction)
|
||||
|
||||
self.presentViewControllerAnimated(controller)
|
||||
})
|
||||
}
|
||||
|
||||
private func presentImagePickerController(source: UIImagePickerControllerSourceType) {
|
||||
dispatch_async(dispatch_get_main_queue(), {
|
||||
let controller = UIImagePickerController()
|
||||
controller.delegate = self
|
||||
var sourceType = source
|
||||
if (!UIImagePickerController.isSourceTypeAvailable(sourceType)) {
|
||||
sourceType = .PhotoLibrary
|
||||
}
|
||||
controller.sourceType = sourceType
|
||||
|
||||
controller.delegate = self
|
||||
self.presentViewControllerAnimated(controller)
|
||||
})
|
||||
}
|
||||
|
||||
private func presentViewControllerAnimated(controller: UIViewController) {
|
||||
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
|
||||
delegate!.window.rootViewController!.presentViewController(controller, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
private func hideViewControler() {
|
||||
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
|
||||
delegate!.window.rootViewController!.dismissViewControllerAnimated(true, completion: nil)
|
||||
}
|
||||
|
||||
private func executeCallback(result: [String: AnyObject]) {
|
||||
if (callback != nil) {
|
||||
callback!([result])
|
||||
callback = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func notifyAboutCancel() {
|
||||
executeCallback(["didCancel": true])
|
||||
}
|
||||
|
||||
private func launchCamera(cameraOptions: [String: AnyObject]) {
|
||||
dispatch_async(dispatch_get_main_queue(), {
|
||||
let cameraViewController = CameraViewController(cameraOptions: cameraOptions)
|
||||
cameraViewController.cameraViewControllerDelegate = self
|
||||
|
||||
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
|
||||
delegate!.window.rootViewController!.presentViewController(cameraViewController, animated: true, completion: nil)
|
||||
})
|
||||
}
|
||||
|
||||
// UIImagePickerControllerDelegate
|
||||
|
||||
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
|
||||
notifyAboutCancel()
|
||||
hideViewControler()
|
||||
}
|
||||
|
||||
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
|
||||
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
|
||||
if !mediaType.isEqualToString(kUTTypeImage as String) {
|
||||
fatalError("Video is not supported")
|
||||
} else {
|
||||
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
|
||||
let imageData = UIImageJPEGRepresentation(image, 1.0)!.base64EncodedStringWithOptions([])
|
||||
executeCallback(["images": [imageData]])
|
||||
}
|
||||
hideViewControler()
|
||||
}
|
||||
|
||||
// CameraViewControllerDelegate
|
||||
|
||||
func imageHasBeenTaken(controller: CameraViewController, imageData: String) {
|
||||
executeCallback(["images": [imageData]])
|
||||
hideViewControler()
|
||||
}
|
||||
|
||||
func cameraViewControllerDidCancel(controller: CameraViewController) {
|
||||
hideViewControler()
|
||||
}
|
||||
|
||||
func onError(controller: CameraViewController, error: String) {
|
||||
executeCallback(["error": [error]])
|
||||
hideViewControler()
|
||||
}
|
||||
}
|
||||
901
ios/ReactNativeCameraKit.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,901 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
|
||||
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
00E356F31AD99517003FC87E /* ReactNativeCameraKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeCameraKitTests.m */; };
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
|
||||
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
8F0E60179CBB773063C32C2F /* Pods_ReactNativeCameraKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD2DB716F7216B9BD5AF69BF /* Pods_ReactNativeCameraKit.framework */; };
|
||||
D1D310CF1CBE9FD9006019A8 /* ReactNativeCameraKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310CE1CBE9FD9006019A8 /* ReactNativeCameraKit.swift */; };
|
||||
D1D310DC1CBEA062006019A8 /* ReactNativeCameraKit.m in Sources */ = {isa = PBXBuildFile; fileRef = D1D310DB1CBEA062006019A8 /* ReactNativeCameraKit.m */; };
|
||||
D1D310DF1CBEA0D0006019A8 /* CropHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310DE1CBEA0D0006019A8 /* CropHelper.swift */; };
|
||||
D1D310E21CBEA15B006019A8 /* CameraSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310E11CBEA15B006019A8 /* CameraSessionManager.swift */; };
|
||||
D1D310E41CBEA17D006019A8 /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310E31CBEA17D006019A8 /* CameraViewController.swift */; };
|
||||
D1D310E61CBEA1AA006019A8 /* CameraViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310E51CBEA1AA006019A8 /* CameraViewControllerDelegate.swift */; };
|
||||
D1D310E81CBEA1CE006019A8 /* PhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310E71CBEA1CE006019A8 /* PhotoViewController.swift */; };
|
||||
D1D310EA1CBEA1E6006019A8 /* PhotoViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D310E91CBEA1E6006019A8 /* PhotoViewControllerDelegate.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTActionSheet;
|
||||
};
|
||||
00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTGeolocation;
|
||||
};
|
||||
00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||
remoteInfo = RCTNetwork;
|
||||
};
|
||||
00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
|
||||
remoteInfo = RCTVibration;
|
||||
};
|
||||
00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||
remoteInfo = ReactNativeCameraKit;
|
||||
};
|
||||
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTSettings;
|
||||
};
|
||||
139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
146834031AC3E56700842450 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTLinking;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
|
||||
00E356EE1AD99517003FC87E /* ReactNativeCameraKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeCameraKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* ReactNativeCameraKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCameraKitTests.m; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* ReactNativeCameraKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeCameraKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ReactNativeCameraKit/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ReactNativeCameraKit/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeCameraKit/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeCameraKit/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeCameraKit/main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
A09C6955B84903CA14AEF620 /* Pods-ReactNativeCameraKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCameraKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
C70242A4D4BE4A42B79CB1E5 /* Pods-ReactNativeCameraKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCameraKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit.release.xcconfig"; sourceTree = "<group>"; };
|
||||
CD2DB716F7216B9BD5AF69BF /* Pods_ReactNativeCameraKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReactNativeCameraKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D1D310CD1CBE9FD9006019A8 /* ReactNativeCameraKit-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativeCameraKit-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
D1D310CE1CBE9FD9006019A8 /* ReactNativeCameraKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReactNativeCameraKit.swift; sourceTree = "<group>"; };
|
||||
D1D310DB1CBEA062006019A8 /* ReactNativeCameraKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCameraKit.m; sourceTree = "<group>"; };
|
||||
D1D310DE1CBEA0D0006019A8 /* CropHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropHelper.swift; sourceTree = "<group>"; };
|
||||
D1D310E11CBEA15B006019A8 /* CameraSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraSessionManager.swift; sourceTree = "<group>"; };
|
||||
D1D310E31CBEA17D006019A8 /* CameraViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = "<group>"; };
|
||||
D1D310E51CBEA1AA006019A8 /* CameraViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraViewControllerDelegate.swift; sourceTree = "<group>"; };
|
||||
D1D310E71CBEA1CE006019A8 /* PhotoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewController.swift; sourceTree = "<group>"; };
|
||||
D1D310E91CBEA1E6006019A8 /* PhotoViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewControllerDelegate.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
00E356EB1AD99517003FC87E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
|
||||
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
|
||||
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
|
||||
8F0E60179CBB773063C32C2F /* Pods_ReactNativeCameraKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
00C302A81ABCB8CE00DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302B61ABCB90400DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302BC1ABCB91800DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302D41ABCB9D200DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302E01ABCB9EE00DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356EF1AD99517003FC87E /* ReactNativeCameraKitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F21AD99517003FC87E /* ReactNativeCameraKitTests.m */,
|
||||
00E356F01AD99517003FC87E /* Supporting Files */,
|
||||
);
|
||||
path = ReactNativeCameraKitTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356F01AD99517003FC87E /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F11AD99517003FC87E /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
139105B71AF99BAD00B5F7CC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
139FDEE71B06529A00C62182 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* ReactNativeCameraKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1D310E01CBEA0F6006019A8 /* Camera */,
|
||||
D1D310DD1CBEA0B4006019A8 /* Helpers */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
D1D310CE1CBE9FD9006019A8 /* ReactNativeCameraKit.swift */,
|
||||
D1D310CD1CBE9FD9006019A8 /* ReactNativeCameraKit-Bridging-Header.h */,
|
||||
D1D310DB1CBEA062006019A8 /* ReactNativeCameraKit.m */,
|
||||
);
|
||||
name = ReactNativeCameraKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
146834001AC3E56700842450 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
146834041AC3E56700842450 /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
660045470EB1C3A662DB6860 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD2DB716F7216B9BD5AF69BF /* Pods_ReactNativeCameraKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
78C398B11ACF4ADC00677621 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */,
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341B11AAA6A8300B99B32 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* ReactNativeCameraKit */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* ReactNativeCameraKitTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
A0D5301919F082B381AED4B2 /* Pods */,
|
||||
660045470EB1C3A662DB6860 /* Frameworks */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* ReactNativeCameraKit.app */,
|
||||
00E356EE1AD99517003FC87E /* ReactNativeCameraKitTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A0D5301919F082B381AED4B2 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A09C6955B84903CA14AEF620 /* Pods-ReactNativeCameraKit.debug.xcconfig */,
|
||||
C70242A4D4BE4A42B79CB1E5 /* Pods-ReactNativeCameraKit.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D1D310DD1CBEA0B4006019A8 /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1D310DE1CBEA0D0006019A8 /* CropHelper.swift */,
|
||||
);
|
||||
name = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D1D310E01CBEA0F6006019A8 /* Camera */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1D310E11CBEA15B006019A8 /* CameraSessionManager.swift */,
|
||||
D1D310E31CBEA17D006019A8 /* CameraViewController.swift */,
|
||||
D1D310E51CBEA1AA006019A8 /* CameraViewControllerDelegate.swift */,
|
||||
D1D310E71CBEA1CE006019A8 /* PhotoViewController.swift */,
|
||||
D1D310E91CBEA1E6006019A8 /* PhotoViewControllerDelegate.swift */,
|
||||
);
|
||||
name = Camera;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
00E356ED1AD99517003FC87E /* ReactNativeCameraKitTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeCameraKitTests" */;
|
||||
buildPhases = (
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */,
|
||||
);
|
||||
name = ReactNativeCameraKitTests;
|
||||
productName = ReactNativeCameraKitTests;
|
||||
productReference = 00E356EE1AD99517003FC87E /* ReactNativeCameraKitTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
13B07F861A680F5B00A75B9A /* ReactNativeCameraKit */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeCameraKit" */;
|
||||
buildPhases = (
|
||||
75BD5BC400E0F0FFB5CA4C9D /* Check Pods Manifest.lock */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
298D3A2F8738131D7D6292FD /* Embed Pods Frameworks */,
|
||||
C901BAD3B5898B500305AA85 /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ReactNativeCameraKit;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* ReactNativeCameraKit.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0720;
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||
};
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
DevelopmentTeam = FALU6K28DC;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "ReactNativeCameraKit" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
|
||||
ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
|
||||
ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
|
||||
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146834001AC3E56700842450 /* Products */;
|
||||
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* ReactNativeCameraKit */,
|
||||
00E356ED1AD99517003FC87E /* ReactNativeCameraKitTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTActionSheet.a;
|
||||
remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTGeolocation.a;
|
||||
remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTNetwork.a;
|
||||
remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTVibration.a;
|
||||
remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTSettings.a;
|
||||
remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
146834041AC3E56700842450 /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTLinking.a;
|
||||
remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
00E356EC1AD99517003FC87E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Bundle React Native code and images";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
|
||||
};
|
||||
298D3A2F8738131D7D6292FD /* Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
75BD5BC400E0F0FFB5CA4C9D /* Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C901BAD3B5898B500305AA85 /* Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReactNativeCameraKit/Pods-ReactNativeCameraKit-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
00E356EA1AD99517003FC87E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00E356F31AD99517003FC87E /* ReactNativeCameraKitTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D1D310EA1CBEA1E6006019A8 /* PhotoViewControllerDelegate.swift in Sources */,
|
||||
D1D310E61CBEA1AA006019A8 /* CameraViewControllerDelegate.swift in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
D1D310DC1CBEA062006019A8 /* ReactNativeCameraKit.m in Sources */,
|
||||
D1D310CF1CBE9FD9006019A8 /* ReactNativeCameraKit.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
D1D310E81CBEA1CE006019A8 /* PhotoViewController.swift in Sources */,
|
||||
D1D310E41CBEA17D006019A8 /* CameraViewController.swift in Sources */,
|
||||
D1D310DF1CBEA0D0006019A8 /* CropHelper.swift in Sources */,
|
||||
D1D310E21CBEA15B006019A8 /* CameraSessionManager.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 13B07F861A680F5B00A75B9A /* ReactNativeCameraKit */;
|
||||
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = ReactNativeCameraKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = ReactNativeCameraKitTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeCameraKit.app/ReactNativeCameraKit";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = ReactNativeCameraKitTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactNativeCameraKit.app/ReactNativeCameraKit";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = A09C6955B84903CA14AEF620 /* Pods-ReactNativeCameraKit.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
);
|
||||
INFOPLIST_FILE = ReactNativeCameraKit/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ReactNativeCameraKit;
|
||||
PRODUCT_NAME = ReactNativeCameraKit;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "ReactNativeCameraKit-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C70242A4D4BE4A42B79CB1E5 /* Pods-ReactNativeCameraKit.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
);
|
||||
INFOPLIST_FILE = ReactNativeCameraKit/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ReactNativeCameraKit;
|
||||
PRODUCT_NAME = ReactNativeCameraKit;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "ReactNativeCameraKit-Bridging-Header.h";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeCameraKitTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
00E356F61AD99517003FC87E /* Debug */,
|
||||
00E356F71AD99517003FC87E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeCameraKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "ReactNativeCameraKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "ReactNativeCameraKit.app"
|
||||
BlueprintName = "ReactNativeCameraKit"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "ReactNativeCameraKitTests.xctest"
|
||||
BlueprintName = "ReactNativeCameraKitTests"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "ReactNativeCameraKitTests.xctest"
|
||||
BlueprintName = "ReactNativeCameraKitTests"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "ReactNativeCameraKit.app"
|
||||
BlueprintName = "ReactNativeCameraKit"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "ReactNativeCameraKit.app"
|
||||
BlueprintName = "ReactNativeCameraKit"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "ReactNativeCameraKit.app"
|
||||
BlueprintName = "ReactNativeCameraKit"
|
||||
ReferencedContainer = "container:ReactNativeCameraKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
10
ios/ReactNativeCameraKit.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:ReactNativeCameraKit.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
16
ios/ReactNativeCameraKit/AppDelegate.h
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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 <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
59
ios/ReactNativeCameraKit/AppDelegate.m
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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 "AppDelegate.h"
|
||||
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
//jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. The static bundle is automatically
|
||||
* generated by the "Bundle React Native code and images" build step when
|
||||
* running the project on an actual device or running the project on the
|
||||
* simulator in the "Release" build configuration.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"ReactNativeCameraKit"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
42
ios/ReactNativeCameraKit/Base.lproj/LaunchScreen.xib
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ReactNativeCameraKit" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
23
ios/ReactNativeCameraKit/Images.xcassets/CloseIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Delete-2.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Delete.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Delete-1.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
ios/ReactNativeCameraKit/Images.xcassets/CloseIcon.imageset/Delete-1.png
vendored
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
ios/ReactNativeCameraKit/Images.xcassets/CloseIcon.imageset/Delete-2.png
vendored
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
ios/ReactNativeCameraKit/Images.xcassets/CloseIcon.imageset/Delete.png
vendored
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
23
ios/ReactNativeCameraKit/Images.xcassets/FlashAutoIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-25.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-50.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-75.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashAutoIcon.imageset/flash_on_filled-25.png
vendored
Normal file
|
After Width: | Height: | Size: 475 B |
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashAutoIcon.imageset/flash_on_filled-50.png
vendored
Normal file
|
After Width: | Height: | Size: 633 B |
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashAutoIcon.imageset/flash_on_filled-75.png
vendored
Normal file
|
After Width: | Height: | Size: 946 B |
23
ios/ReactNativeCameraKit/Images.xcassets/FlashOffIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_off_filled-25.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_off_filled-50.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_off_filled-75.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashOffIcon.imageset/flash_off_filled-25.png
vendored
Normal file
|
After Width: | Height: | Size: 541 B |
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashOffIcon.imageset/flash_off_filled-50.png
vendored
Normal file
|
After Width: | Height: | Size: 734 B |
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashOffIcon.imageset/flash_off_filled-75.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
23
ios/ReactNativeCameraKit/Images.xcassets/FlashOnIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-25.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-50.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "flash_on_filled-75.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
ios/ReactNativeCameraKit/Images.xcassets/FlashOnIcon.imageset/flash_on_filled-25.png
vendored
Normal file
|
After Width: | Height: | Size: 584 B |