Skip to content

use QBImagePicker cocoa pod for iOS #172

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
env:
global:
- ANDROID_PACKAGE='imagepickerdemo-debug.apk'
- ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk
- ANDROID_PACKAGE='app-debug.apk'
- ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk/debug
- ANDROID_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER/$ANDROID_PACKAGE?overwrite=true"
- IOS_PACKAGE='imagepickerdemo.zip'
- IOS_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/ios/build/emulator
Expand Down Expand Up @@ -78,7 +78,7 @@ android:
components:
- tools
- platform-tools
- build-tools-26.0.1
- build-tools-26.0.2
- android-26
- android-23
- extra-android-m2repository
Expand Down
39 changes: 14 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
[![Build Status](https://travis-ci.org/NativeScript/nativescript-imagepicker.svg?branch=master)](https://travis-ci.org/NativeScript/nativescript-imagepicker)

Imagepicker plugin supporting both single and multiple selection.
<br />Plugin supports **iOS8+** and uses [Photos Framework](https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/Photos_Framework/index.html).
<br />Plugin supports **iOS8+** and uses [QBImagePicker](https://github.com/questbeat/QBImagePicker) cocoa pod.
<br />For **Android** it uses Intents to open the stock images or file pickers. For Android 6 (API 23) and above the permissions to read file storage should be explicitly required. See demo for implementation details.

<!-- TOC depthFrom:2 -->

- [Installation](#installation)
- [Configuration](#configuration)
- [Migrating from 5.x.x to 6.x.x](#migrating-from-5xx-to-6xx)
- [Migrating from 4.x.x to 5.x.x](#migrating-from-4xx-to-5xx)
- [Migrating from 3.x.x to 4.x.x](#migrating-from-3xx-to-4xx)
- [Usage](#usage)
Expand Down Expand Up @@ -41,6 +42,9 @@ tns run
## Configuration
No additional configuration required!

## Migrating from 5.x.x to 6.x.x
With version **6.x.x** the dependency to the `nativescript-ui-listview` plugin is removed and for iOS the [QBImagePicker](https://github.com/questbeat/QBImagePicker) cocoa pod is used. Now the plugin supports some new features, fixes some bugs and looks super native for iOS. You can remove any dependencies to `nativescript-pro-ui`, `nativescript-ui-listview`, etc. in case you've added them in your app specifically for this plugin. Also the options **doneText**, **cancelText**, **albumsText**, **newestFirst** and the methods **cancel()** and **done()** are no longer applicable. The image picker now returns the basic [{N} ImageAsset class](https://github.com/NativeScript/NativeScript/tree/master/tns-core-modules/image-asset) (and not custom asset as before).

## Migrating from 4.x.x to 5.x.x
With version **5.x.x** major update to the plugin there is a related dependency which needs to be updated inside your project. The plugin uses internally the `nativescript-ui-listview` plugin (part of the NativeScript Pro UI components). Recently the monolithic [NativeScript Pro UI plugin was split in multiple plugins](https://www.nativescript.org/blog/professional-components-from-nativescript-ui-the-big-breakup), each of them representing a single component. Now, instead of the monolithic package, nativescript-imagepicker uses only the component it needs. To use version 5.x.x of the plugin, you need to update any dependencies to `nativescript-pro-ui` in your project with the single component alternatives as described in the [migration guide](http://docs.telerik.com/devtools/nativescript-ui/migration).

Expand Down Expand Up @@ -116,33 +120,18 @@ context
| Option | Platform | Default | Description |
| --- | --- | --- | --- |
| mode | both | multiple | The mode if the imagepicker. Possible values are `single` for single selection and `multiple` for multiple selection. |
| doneText | iOS | Done | The text of the "Done" button on top right. |
| cancelText | iOS | Cancel | The text of the "Cancel" button on top left. |
| albumsText | iOS | Albums | The title of the "Albums" screen from where the selection of album and images can be done. |
| newestFirst | iOS | false | Set to `true` to sort the images in an album by newest first. |
| minimumNumberOfSelection | iOS | 0 | The minumum number of selected assets. |
| maximumNumberOfSelection | iOS | 0 | The maximum number of selected assets. |
| showsNumberOfSelectedAssets | iOS | True | Display the number of selected assets. |
| prompt | iOS | undefined | Display prompt text when selecting assets. |
| numberOfColumnsInPortrait | iOS | 4 | Set the number of columns in Portrait orientation. |
| numberOfColumnsInLandscape | iOS | 7 | Set the number of columns in Landscape orientation. |
| mediaType | iOS | Any | Choose whether to pick Image/Video/Any type of assets. |

The **hostView** parameter can be set to the view that hosts the image picker. Applicable in iOS only, intended to be used when open picker from a modal page.

* authorize() - request the required permissions.
* present() - show the albums to present the user the ability to select images. Returns an array of the selected images.
* cancel() - cancel selection. iOS only.
* done() - confirm the selection is ready. iOS only.


### Properties
| Property | Default | Description |
| --- | --- | --- |
| selection | null | An array of selected image assets. |
| albums | null | Albums from where the images are picked. |


### Image properties

Once image is picked some options can be applied to it before it is used:

| Option | Default | Description |
| --- | --- | --- |
| maxWidth | null | Image max width |
| maxHeight | null | Image max height |
| aspectRatio | fit | iOS only. Possible values are `fit` and `fill`. [Read more](https://developer.apple.com/documentation/photos/phimagecontentmode) |

## Contribute
We love PRs! Check out the [contributing guidelines](CONTRIBUTING.md). If you want to contribute, but you are not sure where to start - look for [issues labeled `help wanted`](https://github.com/NativeScript/nativescript-imagepicker/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
Expand Down
20 changes: 12 additions & 8 deletions demo-angular/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
</ActionBar>

<GridLayout rows="*, auto, auto">
<ScrollView>
<StackLayout>
<GridLayout height="94" columns="94, *" rows="*, *" *ngFor="let item of items">
<Image rowSpan="2" width="94" height="94" [src]="item"></Image>
<Label col="1" [text]="item.uri"></Label>
<Label col="1" row="1" [text]="item.fileUri"></Label>
<ListView [items]="imageAssets">
<ng-template let-image="item" let-i="index">
<GridLayout columns="auto, *">
<Image
[width]="thumbSize"
[height]="thumbSize"
[src]="image" stretch="fill"></Image>
<Label col="1" [text]="'image ' + i"></Label>
</GridLayout>
</StackLayout>
</ScrollView>
</ng-template>
</ListView>

<Image [src]="imageSrc" *ngIf="isSingleMode" [width]="previewSize" [height]="previewSize" stretch="aspectFit"></Image>
<Button row="1" text="Pick Single" (tap)="onSelectSingleTap()" horizontalAlignment="center"></Button>
<Button row="2" text="Pick Multiple" (tap)="onSelectMultipleTap()" horizontalAlignment="center"></Button>
</GridLayout>
43 changes: 24 additions & 19 deletions demo-angular/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,56 @@
import { Component, ChangeDetectorRef } from "@angular/core";
import { ListView } from "tns-core-modules/ui/list-view";
import { isAndroid } from "tns-core-modules/platform";
import { Component } from "@angular/core";
import * as imagepicker from "nativescript-imagepicker";

@Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent {
imageAssets = [];
imageSrc: any;
isSingleMode: boolean = true;
thumbSize: number = 80;
previewSize: number = 300;

items = [];
public onSelectMultipleTap() {
this.isSingleMode = false;

constructor(private _changeDetectionRef: ChangeDetectorRef) {
}

onSelectMultipleTap() {
let context = imagepicker.create({
mode: "multiple"
});
this.startSelection(context);
}

onSelectSingleTap() {
public onSelectSingleTap() {
this.isSingleMode = true;

let context = imagepicker.create({
mode: "single"
});
this.startSelection(context);
}

startSelection(context) {
let _that = this;
private startSelection(context) {
let that = this;

context
.authorize()
.then(() => {
_that.items = [];
that.imageAssets = [];
that.imageSrc = null;
return context.present();
})
.then((selection) => {
console.log("Selection done:");
selection.forEach(function (selected) {
console.log("----------------");
console.log("uri: " + selected.uri);
console.log("fileUri: " + selected.fileUri);
console.log("Selection done: " + JSON.stringify(selection));
that.imageSrc = that.isSingleMode && selection.length > 0 ? selection[0] : null;

// set the images to be loaded from the assets with optimal sizes (optimize memory usage)
selection.forEach(function (element) {
element.options.width = that.isSingleMode ? that.previewSize : that.thumbSize;
element.options.height = that.isSingleMode ? that.previewSize : that.thumbSize;
});
_that.items = selection;
_that._changeDetectionRef.detectChanges();

that.imageAssets = selection;
}).catch(function (e) {
console.log(e);
});
Expand Down
2 changes: 1 addition & 1 deletion demo-angular/app/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import { AppModule } from "./app.module";

platformNativeScriptDynamic().bootstrapModule(AppModule);
platformNativeScriptDynamic({ createFrameOnBootstrap: true }).bootstrapModule(AppModule);
11 changes: 6 additions & 5 deletions demo-angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"nativescript": {
"id": "org.nativescript.imagepickerdemoangular",
"tns-ios": {
"version": "3.4.0"
"version": "4.0.1"
},
"tns-android": {
"version": "3.4.0"
"version": "4.0.0"
}
},
"dependencies": {
Expand All @@ -23,7 +23,7 @@
"nativescript-unit-test-runner": "^0.3.4",
"reflect-metadata": "~0.1.8",
"rxjs": "^5.5.0",
"tns-core-modules": "^3.4.0"
"tns-core-modules": "^4.0.0"
},
"devDependencies": {
"@angular/compiler-cli": "~5.0.0",
Expand All @@ -42,7 +42,7 @@
"lazy": "1.0.11",
"nativescript-css-loader": "~0.26.0",
"nativescript-dev-typescript": "^0.6.0",
"nativescript-dev-webpack": "^0.9.0",
"nativescript-dev-webpack": "^0.10.1",
"nativescript-worker-loader": "~0.8.1",
"raw-loader": "~0.5.1",
"resolve-url-loader": "~2.1.0",
Expand All @@ -52,7 +52,8 @@
"webpack": "~3.8.1",
"webpack-bundle-analyzer": "^2.8.2",
"webpack-sources": "~1.0.1",
"zone.js": "^0.8.4"
"zone.js": "^0.8.4",
"uglifyjs-webpack-plugin": "~1.1.6"
},
"scripts": {
"build.plugin": "cd ../src && npm run build",
Expand Down
48 changes: 4 additions & 44 deletions demo/app/main-page.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,10 @@
import { EventData } from 'tns-core-modules/data/observable';
import { Page } from 'tns-core-modules/ui/page';
import { isAndroid } from "tns-core-modules/platform";
import * as imagepicker from "nativescript-imagepicker";
import { MainViewModel } from './main-view-model';

let list;
let imageSrc;

export function pageLoaded(args: EventData) {
export function onNavigatingTo(args: EventData) {
let viewModel = new MainViewModel();
let page = <Page>args.object;
list = page.getViewById("urls-list");
imageSrc = page.getViewById("imageSrc");
}

export function onSelectMultipleTap(args) {
let context = imagepicker.create({ mode: "multiple" });
startSelection(context, false);
}

export function onSelectSingleTap(args) {
let context = imagepicker.create({ mode: "single" });
startSelection(context, true);
}

function startSelection(context, isSingle) {
context
.authorize()
.then(function() {
list.items = [];
return context.present();
})
.then(function(selection) {
console.log("Selection done:");
selection.forEach(function(selected) {
console.log("----------------");
console.log("uri: " + selected.uri);
if (isSingle) {
selected.getImage({ maxWidth: 200, maxHeight: 200, aspectRatio: 'fill' })
.then((imageSource) => {
imageSrc.src = imageSource;
});
} else {
imageSrc.visibility = 'hidden';
}
});
list.items = selection;
}).catch(function (e) {
console.log(e);
});
page.bindingContext = viewModel;
}
18 changes: 8 additions & 10 deletions demo/app/main-page.xml
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">
<Page.actionBar>
<ActionBar title="Image Picker" />
</Page.actionBar>
<GridLayout rows="*, auto, auto">
<ListView id="urls-list">
<ListView itemLoading="{{ onItemLoading }}" items="{{ imageAssets }}">
<ListView.itemTemplate>
<GridLayout columns="94, *" rows="*, *">
<Image rowSpan="2" width="80" height="80" src="{{ $value }}" />
<Label col="1" text="{{ uri }}" />
<Label col="1" row="1" text="{{ fileUri }}" />
<GridLayout columns="auto, *">
<Image width="{{ $parents['ListView'].thumbSize }}" height="{{ $parents['ListView'].thumbSize }}" src="{{ $value }}" stretch="fill" />
<Label class="m-10" id="imageLabel" col="1" />
</GridLayout>
</ListView.itemTemplate>
</ListView>

<Image id="imageSrc" width="200" height="200" />
<Button row="1" text="Pick Single" tap="onSelectSingleTap" horizontalAlignment="center" />
<Button row="2" text="Pick Multiple" tap="onSelectMultipleTap" horizontalAlignment="center" />
<Image src="{{ imageSrc }}" visibility="{{ isSingleMode ? 'visible' : 'collapsed' }}" width="{{ previewSize }}" height="{{ previewSize }}" stretch="aspectFit" />
<Button row="1" text="Pick Single" tap="{{ onSelectSingleTap }}" horizontalAlignment="center" />
<Button row="2" text="Pick Multiple" tap="{{ onSelectMultipleTap }}" horizontalAlignment="center" />
</GridLayout>
</Page>
Loading