Skip to content

Commit 9fa315f

Browse files
authored
Merge pull request #172 from NativeScript/tbozhikov/cleanup-image-picker
use QBImagePicker cocoa pod for iOS
2 parents beb51cd + 4a12870 commit 9fa315f

24 files changed

+530
-1076
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
env:
22
global:
3-
- ANDROID_PACKAGE='imagepickerdemo-debug.apk'
4-
- ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk
3+
- ANDROID_PACKAGE='app-debug.apk'
4+
- ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk/debug
55
- ANDROID_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER/$ANDROID_PACKAGE?overwrite=true"
66
- IOS_PACKAGE='imagepickerdemo.zip'
77
- IOS_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/ios/build/emulator
@@ -78,7 +78,7 @@ android:
7878
components:
7979
- tools
8080
- platform-tools
81-
- build-tools-26.0.1
81+
- build-tools-26.0.2
8282
- android-26
8383
- android-23
8484
- extra-android-m2repository

README.md

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
[![Build Status](https://travis-ci.org/NativeScript/nativescript-imagepicker.svg?branch=master)](https://travis-ci.org/NativeScript/nativescript-imagepicker)
77

88
Imagepicker plugin supporting both single and multiple selection.
9-
<br />Plugin supports **iOS8+** and uses [Photos Framework](https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/Photos_Framework/index.html).
9+
<br />Plugin supports **iOS8+** and uses [QBImagePicker](https://github.com/questbeat/QBImagePicker) cocoa pod.
1010
<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.
1111

1212
<!-- TOC depthFrom:2 -->
1313

1414
- [Installation](#installation)
1515
- [Configuration](#configuration)
16+
- [Migrating from 5.x.x to 6.x.x](#migrating-from-5xx-to-6xx)
1617
- [Migrating from 4.x.x to 5.x.x](#migrating-from-4xx-to-5xx)
1718
- [Migrating from 3.x.x to 4.x.x](#migrating-from-3xx-to-4xx)
1819
- [Usage](#usage)
@@ -41,6 +42,9 @@ tns run
4142
## Configuration
4243
No additional configuration required!
4344

45+
## Migrating from 5.x.x to 6.x.x
46+
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).
47+
4448
## Migrating from 4.x.x to 5.x.x
4549
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).
4650

@@ -116,33 +120,18 @@ context
116120
| Option | Platform | Default | Description |
117121
| --- | --- | --- | --- |
118122
| mode | both | multiple | The mode if the imagepicker. Possible values are `single` for single selection and `multiple` for multiple selection. |
119-
| doneText | iOS | Done | The text of the "Done" button on top right. |
120-
| cancelText | iOS | Cancel | The text of the "Cancel" button on top left. |
121-
| albumsText | iOS | Albums | The title of the "Albums" screen from where the selection of album and images can be done. |
122-
| newestFirst | iOS | false | Set to `true` to sort the images in an album by newest first. |
123+
| minimumNumberOfSelection | iOS | 0 | The minumum number of selected assets. |
124+
| maximumNumberOfSelection | iOS | 0 | The maximum number of selected assets. |
125+
| showsNumberOfSelectedAssets | iOS | True | Display the number of selected assets. |
126+
| prompt | iOS | undefined | Display prompt text when selecting assets. |
127+
| numberOfColumnsInPortrait | iOS | 4 | Set the number of columns in Portrait orientation. |
128+
| numberOfColumnsInLandscape | iOS | 7 | Set the number of columns in Landscape orientation. |
129+
| mediaType | iOS | Any | Choose whether to pick Image/Video/Any type of assets. |
130+
131+
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.
123132
124133
* authorize() - request the required permissions.
125134
* present() - show the albums to present the user the ability to select images. Returns an array of the selected images.
126-
* cancel() - cancel selection. iOS only.
127-
* done() - confirm the selection is ready. iOS only.
128-
129-
130-
### Properties
131-
| Property | Default | Description |
132-
| --- | --- | --- |
133-
| selection | null | An array of selected image assets. |
134-
| albums | null | Albums from where the images are picked. |
135-
136-
137-
### Image properties
138-
139-
Once image is picked some options can be applied to it before it is used:
140-
141-
| Option | Default | Description |
142-
| --- | --- | --- |
143-
| maxWidth | null | Image max width |
144-
| maxHeight | null | Image max height |
145-
| aspectRatio | fit | iOS only. Possible values are `fit` and `fill`. [Read more](https://developer.apple.com/documentation/photos/phimagecontentmode) |
146135
147136
## Contribute
148137
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).

demo-angular/app/app.component.html

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
</ActionBar>
44

55
<GridLayout rows="*, auto, auto">
6-
<ScrollView>
7-
<StackLayout>
8-
<GridLayout height="94" columns="94, *" rows="*, *" *ngFor="let item of items">
9-
<Image rowSpan="2" width="94" height="94" [src]="item"></Image>
10-
<Label col="1" [text]="item.uri"></Label>
11-
<Label col="1" row="1" [text]="item.fileUri"></Label>
6+
<ListView [items]="imageAssets">
7+
<ng-template let-image="item" let-i="index">
8+
<GridLayout columns="auto, *">
9+
<Image
10+
[width]="thumbSize"
11+
[height]="thumbSize"
12+
[src]="image" stretch="fill"></Image>
13+
<Label col="1" [text]="'image ' + i"></Label>
1214
</GridLayout>
13-
</StackLayout>
14-
</ScrollView>
15+
</ng-template>
16+
</ListView>
17+
18+
<Image [src]="imageSrc" *ngIf="isSingleMode" [width]="previewSize" [height]="previewSize" stretch="aspectFit"></Image>
1519
<Button row="1" text="Pick Single" (tap)="onSelectSingleTap()" horizontalAlignment="center"></Button>
1620
<Button row="2" text="Pick Multiple" (tap)="onSelectMultipleTap()" horizontalAlignment="center"></Button>
1721
</GridLayout>

demo-angular/app/app.component.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,56 @@
1-
import { Component, ChangeDetectorRef } from "@angular/core";
2-
import { ListView } from "tns-core-modules/ui/list-view";
3-
import { isAndroid } from "tns-core-modules/platform";
1+
import { Component } from "@angular/core";
42
import * as imagepicker from "nativescript-imagepicker";
53

64
@Component({
75
selector: "my-app",
86
templateUrl: "app.component.html",
97
})
108
export class AppComponent {
9+
imageAssets = [];
10+
imageSrc: any;
11+
isSingleMode: boolean = true;
12+
thumbSize: number = 80;
13+
previewSize: number = 300;
1114

12-
items = [];
15+
public onSelectMultipleTap() {
16+
this.isSingleMode = false;
1317

14-
constructor(private _changeDetectionRef: ChangeDetectorRef) {
15-
}
16-
17-
onSelectMultipleTap() {
1818
let context = imagepicker.create({
1919
mode: "multiple"
2020
});
2121
this.startSelection(context);
2222
}
2323

24-
onSelectSingleTap() {
24+
public onSelectSingleTap() {
25+
this.isSingleMode = true;
26+
2527
let context = imagepicker.create({
2628
mode: "single"
2729
});
2830
this.startSelection(context);
2931
}
3032

31-
startSelection(context) {
32-
let _that = this;
33+
private startSelection(context) {
34+
let that = this;
3335

3436
context
3537
.authorize()
3638
.then(() => {
37-
_that.items = [];
39+
that.imageAssets = [];
40+
that.imageSrc = null;
3841
return context.present();
3942
})
4043
.then((selection) => {
41-
console.log("Selection done:");
42-
selection.forEach(function (selected) {
43-
console.log("----------------");
44-
console.log("uri: " + selected.uri);
45-
console.log("fileUri: " + selected.fileUri);
44+
console.log("Selection done: " + JSON.stringify(selection));
45+
that.imageSrc = that.isSingleMode && selection.length > 0 ? selection[0] : null;
46+
47+
// set the images to be loaded from the assets with optimal sizes (optimize memory usage)
48+
selection.forEach(function (element) {
49+
element.options.width = that.isSingleMode ? that.previewSize : that.thumbSize;
50+
element.options.height = that.isSingleMode ? that.previewSize : that.thumbSize;
4651
});
47-
_that.items = selection;
48-
_that._changeDetectionRef.detectChanges();
52+
53+
that.imageAssets = selection;
4954
}).catch(function (e) {
5055
console.log(e);
5156
});

demo-angular/app/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
22
import { AppModule } from "./app.module";
33

4-
platformNativeScriptDynamic().bootstrapModule(AppModule);
4+
platformNativeScriptDynamic({ createFrameOnBootstrap: true }).bootstrapModule(AppModule);

demo-angular/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"nativescript": {
33
"id": "org.nativescript.imagepickerdemoangular",
44
"tns-ios": {
5-
"version": "3.4.0"
5+
"version": "4.0.1"
66
},
77
"tns-android": {
8-
"version": "3.4.0"
8+
"version": "4.0.0"
99
}
1010
},
1111
"dependencies": {
@@ -23,7 +23,7 @@
2323
"nativescript-unit-test-runner": "^0.3.4",
2424
"reflect-metadata": "~0.1.8",
2525
"rxjs": "^5.5.0",
26-
"tns-core-modules": "^3.4.0"
26+
"tns-core-modules": "^4.0.0"
2727
},
2828
"devDependencies": {
2929
"@angular/compiler-cli": "~5.0.0",
@@ -42,7 +42,7 @@
4242
"lazy": "1.0.11",
4343
"nativescript-css-loader": "~0.26.0",
4444
"nativescript-dev-typescript": "^0.6.0",
45-
"nativescript-dev-webpack": "^0.9.0",
45+
"nativescript-dev-webpack": "^0.10.1",
4646
"nativescript-worker-loader": "~0.8.1",
4747
"raw-loader": "~0.5.1",
4848
"resolve-url-loader": "~2.1.0",
@@ -52,7 +52,8 @@
5252
"webpack": "~3.8.1",
5353
"webpack-bundle-analyzer": "^2.8.2",
5454
"webpack-sources": "~1.0.1",
55-
"zone.js": "^0.8.4"
55+
"zone.js": "^0.8.4",
56+
"uglifyjs-webpack-plugin": "~1.1.6"
5657
},
5758
"scripts": {
5859
"build.plugin": "cd ../src && npm run build",

demo/app/main-page.ts

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,10 @@
11
import { EventData } from 'tns-core-modules/data/observable';
22
import { Page } from 'tns-core-modules/ui/page';
3-
import { isAndroid } from "tns-core-modules/platform";
4-
import * as imagepicker from "nativescript-imagepicker";
3+
import { MainViewModel } from './main-view-model';
54

6-
let list;
7-
let imageSrc;
8-
9-
export function pageLoaded(args: EventData) {
5+
export function onNavigatingTo(args: EventData) {
6+
let viewModel = new MainViewModel();
107
let page = <Page>args.object;
11-
list = page.getViewById("urls-list");
12-
imageSrc = page.getViewById("imageSrc");
13-
}
14-
15-
export function onSelectMultipleTap(args) {
16-
let context = imagepicker.create({ mode: "multiple" });
17-
startSelection(context, false);
18-
}
19-
20-
export function onSelectSingleTap(args) {
21-
let context = imagepicker.create({ mode: "single" });
22-
startSelection(context, true);
23-
}
248

25-
function startSelection(context, isSingle) {
26-
context
27-
.authorize()
28-
.then(function() {
29-
list.items = [];
30-
return context.present();
31-
})
32-
.then(function(selection) {
33-
console.log("Selection done:");
34-
selection.forEach(function(selected) {
35-
console.log("----------------");
36-
console.log("uri: " + selected.uri);
37-
if (isSingle) {
38-
selected.getImage({ maxWidth: 200, maxHeight: 200, aspectRatio: 'fill' })
39-
.then((imageSource) => {
40-
imageSrc.src = imageSource;
41-
});
42-
} else {
43-
imageSrc.visibility = 'hidden';
44-
}
45-
});
46-
list.items = selection;
47-
}).catch(function (e) {
48-
console.log(e);
49-
});
9+
page.bindingContext = viewModel;
5010
}

demo/app/main-page.xml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
1+
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">
22
<Page.actionBar>
33
<ActionBar title="Image Picker" />
44
</Page.actionBar>
55
<GridLayout rows="*, auto, auto">
6-
<ListView id="urls-list">
6+
<ListView itemLoading="{{ onItemLoading }}" items="{{ imageAssets }}">
77
<ListView.itemTemplate>
8-
<GridLayout columns="94, *" rows="*, *">
9-
<Image rowSpan="2" width="80" height="80" src="{{ $value }}" />
10-
<Label col="1" text="{{ uri }}" />
11-
<Label col="1" row="1" text="{{ fileUri }}" />
8+
<GridLayout columns="auto, *">
9+
<Image width="{{ $parents['ListView'].thumbSize }}" height="{{ $parents['ListView'].thumbSize }}" src="{{ $value }}" stretch="fill" />
10+
<Label class="m-10" id="imageLabel" col="1" />
1211
</GridLayout>
1312
</ListView.itemTemplate>
1413
</ListView>
15-
16-
<Image id="imageSrc" width="200" height="200" />
17-
<Button row="1" text="Pick Single" tap="onSelectSingleTap" horizontalAlignment="center" />
18-
<Button row="2" text="Pick Multiple" tap="onSelectMultipleTap" horizontalAlignment="center" />
14+
<Image src="{{ imageSrc }}" visibility="{{ isSingleMode ? 'visible' : 'collapsed' }}" width="{{ previewSize }}" height="{{ previewSize }}" stretch="aspectFit" />
15+
<Button row="1" text="Pick Single" tap="{{ onSelectSingleTap }}" horizontalAlignment="center" />
16+
<Button row="2" text="Pick Multiple" tap="{{ onSelectMultipleTap }}" horizontalAlignment="center" />
1917
</GridLayout>
2018
</Page>

0 commit comments

Comments
 (0)