Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.

Commit de69f9a

Browse files
committed
Merge branch 'release/0.14'
2 parents ceace39 + d5ad354 commit de69f9a

16 files changed

+346
-39
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
### Expected behavior
2+
3+
4+
### Actual behavior
5+
6+
7+
### Steps to reproduce the behavior
8+
9+
10+
##### Tested on [device], iOS [version], WPiOS [version]

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fixes #
2+
3+
To test:
4+

CONTRIBUTING.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Contributing to WPMediaPicker
2+
3+
Hi! Thank you for your interest in contributing to the app, we really appreciate it.
4+
5+
There are many ways to contribute – reporting bugs, feature suggestions, fixing bugs, submitting pull requests for enhancements.
6+
7+
## Reporting Bugs, Asking Questions, Sending Suggestions
8+
9+
Just [file a GitHub issue](https://github.com/wordpress-mobile/MediaPicker-iOS/issues), that’s all. If you want to prefix the title with a “Question:”, “Bug:”, "Feature Request:", or the general area of the application, that would be helpful, but by no means mandatory. If you have write access, add the appropriate labels.
10+
11+
If you’re filing a bug, specific steps to reproduce are helpful. Please include the part of the app that has the bug, along with what you expected to see and what happened instead. A screenshot is always helpful as well.
12+
13+
## Submitting code changes
14+
15+
We welcome Pull Requests for bug fixes on any open issues that you'd like to contribute! More details on our process can be found in the [Make WordPress Mobile handbook](https://make.wordpress.org/mobile/handbook/pathways/ios/), specifically [here](https://make.wordpress.org/mobile/handbook/pathways/ios/how-to-contribute/).
16+
17+
## Discussion
18+
19+
Aside from writing issues and pull requests, you can also hang out in the #mobile WordPress.org Slack channel with other WordPress Mobile developers/contributors. Check out chat.wordpress.org for instructions on how to create an account in Slack.
20+
21+
The purpose of the Slack chat is to provide updates about ongoing initiatives regarding the mobile apps and to discuss, prioritize and coordinate future changes. If you have questions, Slack chat is a great place to start.
22+
23+
## Contribute to translations
24+
25+
We use a tool called GlotPress to manage translations. The WordPress-iOS GlotPress instance lives [here](http://translate.wordpress.org/projects/apps/ios/dev). To add new translations or fix existing ones, create an account over at GlotPress and submit your changes over at the GlotPress site.

Example/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
PODS:
2-
- WPMediaPicker (0.13)
2+
- WPMediaPicker (0.14)
33

44
DEPENDENCIES:
55
- WPMediaPicker (from `../`)
66

77
EXTERNAL SOURCES:
88
WPMediaPicker:
9-
:path: "../"
9+
:path: ../
1010

1111
SPEC CHECKSUMS:
12-
WPMediaPicker: 5f39880ac799dbbf41a99f73567a95ab5297dc93
12+
WPMediaPicker: af44371d5f815b34f4c211138c6520bb5f495718
1313

1414
PODFILE CHECKSUM: 7855568785f801c5559f8e70856ad87de227dc95
1515

Example/WPMediaPicker.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
B5FF3BE91CAD8AB100C1D597 /* PostProcessingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostProcessingViewController.m; sourceTree = "<group>"; };
7070
CEF4FB57530C0C9D7C09607C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
7171
F0D09511821A352B062D5699 /* WPMediaPicker.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = WPMediaPicker.podspec; path = ../WPMediaPicker.podspec; sourceTree = "<group>"; };
72+
FF7DCB451E7C494D00AB77CB /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = CONTRIBUTING.md; path = ../CONTRIBUTING.md; sourceTree = "<group>"; };
7273
FFC3F6F21B0D9BB100EFC359 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = "<group>"; };
7374
FFE69A1B1B14AB840073C2EB /* OptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionsViewController.h; sourceTree = "<group>"; };
7475
FFE69A1C1B14AB840073C2EB /* OptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionsViewController.m; sourceTree = "<group>"; };
@@ -191,6 +192,7 @@
191192
children = (
192193
F0D09511821A352B062D5699 /* WPMediaPicker.podspec */,
193194
CEF4FB57530C0C9D7C09607C /* README.md */,
195+
FF7DCB451E7C494D00AB77CB /* CONTRIBUTING.md */,
194196
5709B45B57F590232B3E5DA7 /* LICENSE */,
195197
);
196198
name = "Podspec Metadata";

Example/WPMediaPicker/DemoViewController.m

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
#import "OptionsViewController.h"
55
#import "PostProcessingViewController.h"
66
#import <WPMediaPicker/WPMediaPicker.h>
7-
#import <WPMediaPicker/WPMediaGroupTableViewCell.h>
8-
#import <WPMediaPicker/WPMediaPicker.h>
97

10-
@interface DemoViewController () <WPMediaPickerViewControllerDelegate, OptionsViewControllerDelegate>
8+
@interface DemoViewController () <WPMediaPickerViewControllerDelegate, OptionsViewControllerDelegate, UITextFieldDelegate>
119

1210
@property (nonatomic, strong) NSArray * assets;
1311
@property (nonatomic, strong) NSDateFormatter * dateFormatter;
1412
@property (nonatomic, strong) id<WPMediaCollectionDataSource> customDataSource;
1513
@property (nonatomic, copy) NSDictionary *options;
1614
@property (nonatomic, strong) WPNavigationMediaPickerViewController *mediaPicker;
15+
@property (nonatomic, strong) UITextField *quickInputTextField;
16+
@property (nonatomic, strong) WPInputMediaPickerViewController *mediaInputViewController;
17+
@property (nonatomic, strong) UIView* wasFirstResponder;
1718

1819
@end
1920

@@ -45,10 +46,20 @@ - (void)viewDidLoad
4546

4647
}
4748

48-
- (void)didReceiveMemoryWarning
49-
{
50-
[super didReceiveMemoryWarning];
51-
// Dispose of any resources that can be recreated.
49+
- (void)viewWillDisappear:(BOOL)animated {
50+
if (self.quickInputTextField.isFirstResponder) {
51+
self.wasFirstResponder = self.quickInputTextField;
52+
} else {
53+
self.wasFirstResponder = nil;
54+
}
55+
[super viewWillDisappear:animated];
56+
}
57+
58+
- (void)viewWillAppear:(BOOL)animated {
59+
if (self.wasFirstResponder != nil && self.wasFirstResponder == self.quickInputTextField) {
60+
[self.quickInputTextField becomeFirstResponder];
61+
}
62+
[super viewWillAppear:animated];
5263
}
5364

5465
#pragma - UITableViewControllerDelegate
@@ -63,7 +74,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
6374
return self.assets.count;
6475
}
6576

66-
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
77+
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
6778
{
6879
WPMediaGroupTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass([WPMediaGroupTableViewCell class]) forIndexPath:indexPath];
6980

@@ -92,10 +103,58 @@ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(
92103
return cell;
93104
}
94105

106+
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
107+
UIView *viewHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 44)];
108+
[viewHeaderView addSubview:self.quickInputTextField];
109+
self.quickInputTextField.frame = CGRectInset(viewHeaderView.frame, 2, 2);
110+
self.quickInputTextField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
111+
return viewHeaderView;
112+
}
113+
114+
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
115+
return 44.0;
116+
}
117+
118+
- (UITextField *)quickInputTextField {
119+
if (_quickInputTextField) {
120+
return _quickInputTextField;
121+
}
122+
_quickInputTextField = [[UITextField alloc] initWithFrame:CGRectInset(CGRectMake(0, 0, self.view.frame.size.width, 44), 5, 2)];
123+
_quickInputTextField.placeholder = @"Tap here to quick select assets";
124+
_quickInputTextField.borderStyle = UITextBorderStyleRoundedRect;
125+
_quickInputTextField.delegate = self;
126+
127+
self.mediaInputViewController = [[WPInputMediaPickerViewController alloc] init];
128+
129+
[self addChildViewController:self.mediaInputViewController];
130+
_quickInputTextField.inputView = self.mediaInputViewController.view;
131+
[self.mediaInputViewController didMoveToParentViewController:self];
132+
133+
self.mediaInputViewController.mediaPickerDelegate = self;
134+
self.mediaInputViewController.mediaPicker.viewControllerToUseToPresent = self;
135+
_quickInputTextField.inputAccessoryView = self.mediaInputViewController.mediaToolbar;
136+
137+
return _quickInputTextField;
138+
}
139+
140+
- (id<WPMediaCollectionDataSource>)defaultDataSource
141+
{
142+
static id<WPMediaCollectionDataSource> assetSource = nil;
143+
static dispatch_once_t onceToken;
144+
dispatch_once(&onceToken, ^{
145+
assetSource = [[WPPHAssetDataSource alloc] init];
146+
});
147+
return assetSource;
148+
}
149+
95150
#pragma - <WPMediaPickerViewControllerDelegate>
96151

97152
- (void)mediaPickerControllerDidCancel:(WPMediaPickerViewController *)picker
98153
{
154+
if (picker == self.mediaInputViewController.mediaPicker) {
155+
[self.quickInputTextField resignFirstResponder];
156+
return;
157+
}
99158
[self dismissViewControllerAnimated:YES completion:nil];
100159
}
101160

@@ -105,6 +164,11 @@ - (void)mediaPickerController:(WPMediaPickerViewController *)picker didFinishPic
105164
self.assets = assets;
106165
[self.tableView reloadData];
107166

167+
if (picker == self.mediaInputViewController.mediaPicker) {
168+
[self.quickInputTextField resignFirstResponder];
169+
return;
170+
}
171+
108172
// PostProcessing is Optional!
109173
if ([self.options[MediaPickerOptionsPostProcessingStep] boolValue] == false) {
110174
[self dismissViewControllerAnimated:YES completion:nil];
@@ -174,4 +238,18 @@ - (void)cancelOptionsViewController:(OptionsViewController *)optionsViewControll
174238
[self.navigationController popViewControllerAnimated:YES];
175239
}
176240

241+
#pragma - UITextFieldDelegate
242+
243+
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
244+
{
245+
if (textField == self.quickInputTextField) {
246+
self.mediaInputViewController.mediaPicker.showMostRecentFirst = [self.options[MediaPickerOptionsShowMostRecentFirst] boolValue];
247+
self.mediaInputViewController.mediaPicker.allowCaptureOfMedia = [self.options[MediaPickerOptionsShowCameraCapture] boolValue];
248+
self.mediaInputViewController.mediaPicker.preferFrontCamera = [self.options[MediaPickerOptionsPreferFrontCamera] boolValue];
249+
self.mediaInputViewController.mediaPicker.allowMultipleSelection = [self.options[MediaPickerOptionsAllowMultipleSelection] boolValue];
250+
self.mediaInputViewController.mediaPicker.filter = [self.options[MediaPickerOptionsFilterType] intValue];
251+
}
252+
return YES;
253+
}
254+
177255
@end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#import <UIKit/UIKit.h>
2+
#import "WPMediaPickerViewController.h"
3+
4+
5+
/**
6+
A class to be used as an input view for an UITextView or UITextField.
7+
8+
The mediaToolbar property provides a toolbar that can be used as the inputAccessoryView for this inputView.
9+
*/
10+
@interface WPInputMediaPickerViewController : UIViewController
11+
12+
/**
13+
The delegate for the WPMediaPickerViewController events
14+
*/
15+
@property (nonatomic, weak) _Nullable id<WPMediaPickerViewControllerDelegate> mediaPickerDelegate;
16+
17+
/**
18+
The object that acts as the data source of the media picker.
19+
20+
@Discussion
21+
If no object is defined before the picker is show then the picker will use a shared data source that access the user media library.
22+
*/
23+
@property (nonatomic, weak) _Nullable id<WPMediaCollectionDataSource> dataSource;
24+
25+
/**
26+
The internal WPMediaPickerViewController that is used to display the media.
27+
*/
28+
@property (nonatomic, readonly) WPMediaPickerViewController * _Nonnull mediaPicker;
29+
30+
/**
31+
A toolbar that can be used as the inputAccessoryView for this inputView.
32+
*/
33+
@property (nonatomic, readonly) UIToolbar * _Nonnull mediaToolbar;
34+
35+
@end
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#import "WPInputMediaPickerViewController.h"
2+
#import "WPPHAssetDataSource.h"
3+
4+
@interface WPInputMediaPickerViewController()
5+
6+
@property (nonatomic, strong) WPMediaPickerViewController *mediaPicker;
7+
@property (nonatomic, strong) UIToolbar *mediaToolbar;
8+
@property (nonatomic, strong) id<WPMediaCollectionDataSource> privateDataSource;
9+
10+
@end
11+
12+
@implementation WPInputMediaPickerViewController
13+
14+
- (void)viewDidLoad
15+
{
16+
[super viewDidLoad];
17+
self.view.backgroundColor = [UIColor redColor];
18+
[self setupMediaPickerViewController];
19+
}
20+
21+
- (void)setupMediaPickerViewController {
22+
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
23+
24+
self.privateDataSource = [[WPPHAssetDataSource alloc] init];
25+
self.mediaPicker = [[WPMediaPickerViewController alloc] init];
26+
self.mediaPicker.dataSource = self.privateDataSource;
27+
28+
29+
[self addChildViewController:self.mediaPicker];
30+
self.mediaPicker.view.frame = self.view.bounds;
31+
self.mediaPicker.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
32+
[self.view addSubview:self.mediaPicker.view];
33+
[self.mediaPicker didMoveToParentViewController:self];
34+
self.mediaPicker.collectionView.alwaysBounceVertical = NO;
35+
36+
self.mediaToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
37+
self.mediaToolbar.items = @[
38+
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(mediaCanceled:)],
39+
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
40+
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(mediaSelected:)]
41+
];
42+
}
43+
44+
- (void)viewDidLayoutSubviews {
45+
[super viewDidLayoutSubviews];
46+
47+
CGFloat spacing = 1.0f;
48+
CGFloat size = floorf((self.view.frame.size.height - spacing) / 2.0);
49+
self.mediaPicker.cameraPreviewSize = CGSizeMake(1.5*size, 1.5*size);
50+
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
51+
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
52+
layout.itemSize = CGSizeMake(size, size);
53+
layout.minimumLineSpacing = spacing;
54+
layout.minimumInteritemSpacing = spacing;
55+
layout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 10);
56+
57+
self.mediaPicker.collectionView.collectionViewLayout = layout;
58+
59+
}
60+
61+
- (void)setDataSource:(id<WPMediaCollectionDataSource>)dataSource {
62+
self.mediaPicker.dataSource = dataSource;
63+
}
64+
65+
- (id<WPMediaCollectionDataSource>)dataSource {
66+
return self.mediaPicker.dataSource;
67+
}
68+
69+
- (void)setMediaPickerDelegate:(id<WPMediaPickerViewControllerDelegate>)mediaPickerDelegate {
70+
self.mediaPicker.mediaPickerDelegate = mediaPickerDelegate;
71+
}
72+
73+
- (id<WPMediaPickerViewControllerDelegate>)mediaPickerDelegate {
74+
return self.mediaPicker.mediaPickerDelegate;
75+
}
76+
77+
- (void)mediaSelected:(UIBarButtonItem *)sender {
78+
if ([self.mediaPickerDelegate respondsToSelector:@selector(mediaPickerController:didFinishPickingAssets:)]) {
79+
[self.mediaPickerDelegate mediaPickerController:self.mediaPicker didFinishPickingAssets:[self.mediaPicker.selectedAssets copy]];
80+
[self.mediaPicker resetState:NO];
81+
}
82+
83+
}
84+
85+
- (void)mediaCanceled:(UIBarButtonItem *)sender {
86+
if ([self.mediaPickerDelegate respondsToSelector:@selector(mediaPickerControllerDidCancel:)]) {
87+
[self.mediaPickerDelegate mediaPickerControllerDidCancel:self.mediaPicker];
88+
[self.mediaPicker resetState:NO];
89+
}
90+
}
91+
92+
93+
@end

Pod/Classes/WPMediaCapturePreviewCollectionView.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ - (void)commonInit
3737
UIImageView *imageView = [[UIImageView alloc] initWithImage:cameraImage];
3838
imageView.center = CGPointMake(CGRectGetWidth(self.frame) / 2.0, CGRectGetHeight(self.frame) / 2.0);
3939
imageView.contentMode = UIViewContentModeScaleAspectFill;
40-
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
40+
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
4141
[self addSubview:imageView];
4242
}
4343

@@ -94,10 +94,10 @@ - (void)startCapture
9494
}
9595
if (!self.session.isRunning){
9696
[self.session startRunning];
97+
self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
9798
dispatch_async(dispatch_get_main_queue(), ^{
9899
[self.captureVideoPreviewLayer removeFromSuperlayer];
99100
CALayer *viewLayer = self.previewView.layer;
100-
self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
101101
self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
102102
self.captureVideoPreviewLayer.frame = viewLayer.bounds;
103103
self.captureVideoPreviewLayer.connection.videoOrientation = [self videoOrientationForInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]];

Pod/Classes/WPMediaPicker.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@
88
#import "WPMediaCapturePreviewCollectionView.h"
99
#import "WPMediaGroupPickerViewController.h"
1010
#import "WPIndexMove.h"
11+
#import "WPInputMediaPickerViewController.h"
12+
#import "WPVideoPlayerView.h"
13+
#import "WPMediaGroupTableViewCell.h"
1114

1215
#endif /* _WPMEDIAPICKER_ */

0 commit comments

Comments
 (0)