From 9b57875a47dae4b9836fea9ac5b7c3bef28a79db Mon Sep 17 00:00:00 2001 From: moritz haarmann Date: Wed, 12 Feb 2014 18:15:24 +0100 Subject: [PATCH] Added Photo Picker functionality to Feedback Composer (#3) --- Classes/BITFeedbackComposeViewController.m | 143 ++++++++++++++++++-- Resources/iconCamera.png | Bin 0 -> 346 bytes Resources/iconCamera@2x.png | Bin 0 -> 642 bytes Support/HockeySDK.xcodeproj/project.pbxproj | 8 ++ 4 files changed, 143 insertions(+), 8 deletions(-) create mode 100755 Resources/iconCamera.png create mode 100755 Resources/iconCamera@2x.png diff --git a/Classes/BITFeedbackComposeViewController.m b/Classes/BITFeedbackComposeViewController.m index c4eda0230c..72004106d9 100644 --- a/Classes/BITFeedbackComposeViewController.m +++ b/Classes/BITFeedbackComposeViewController.m @@ -42,15 +42,22 @@ #import "BITHockeyHelper.h" -@interface BITFeedbackComposeViewController () { +@interface BITFeedbackComposeViewController () { UIStatusBarStyle _statusBarStyle; } @property (nonatomic, weak) BITFeedbackManager *manager; @property (nonatomic, strong) UITextView *textView; +@property (nonatomic, strong) UIView *contentViewContainer; +@property (nonatomic, strong) UIScrollView *photoScrollView; +@property (nonatomic, strong) NSMutableArray *photoScrollViewImageViews; @property (nonatomic, strong) NSString *text; +@property (nonatomic, strong) NSMutableArray *photos; + +@property (nonatomic, strong) UIView *textAccessoryView; + @end @@ -68,6 +75,8 @@ _blockUserDataScreen = NO; _delegate = nil; _manager = [BITHockeyManager sharedHockeyManager].feedbackManager; + _photos = [NSMutableArray new]; + _photoScrollViewImageViews = [NSMutableArray new]; _text = nil; } @@ -122,12 +131,12 @@ frame.size.height = windowSize.width - navBarHeight - modalGap - kbSize.width; } } - [self.textView setFrame:frame]; + [self.contentViewContainer setFrame:frame]; } - (void)keyboardWillBeHidden:(NSNotification*)aNotification { CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); - [self.textView setFrame:frame]; + [self.contentViewContainer setFrame:frame]; } @@ -142,20 +151,49 @@ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(dismissAction:)]; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:BITHockeyLocalizedString(@"HockeyFeedbackComposeSend") style:UIBarButtonItemStyleDone target:self action:@selector(sendAction:)]; + + // Container that contains both the textfield and eventually the photo scroll view on the right side + self.contentViewContainer = [[UIView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:self.contentViewContainer]; + + // message input textfield - self.textView = [[UITextView alloc] initWithFrame:self.view.frame]; + self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; self.textView.font = [UIFont systemFontOfSize:17]; self.textView.delegate = self; self.textView.backgroundColor = [UIColor whiteColor]; self.textView.returnKeyType = UIReturnKeyDefault; - self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth; - [self.view addSubview:self.textView]; + self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + + [self.contentViewContainer addSubview:self.textView]; + + // Add Photo Button + Container that's displayed above the keyboard. + self.textAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 44)]; + self.textAccessoryView.backgroundColor = [UIColor colorWithRed:0.9f green:0.9f blue:0.9f alpha:1.0f]; + UIButton *addPhotoButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [addPhotoButton setTitle:@"+ Add Photo" forState:UIControlStateNormal]; + addPhotoButton.frame = CGRectMake(0, 0, 100, 44); + + [addPhotoButton addTarget:self action:@selector(addPhotoAction:) forControlEvents:UIControlEventTouchUpInside]; + + [self.textAccessoryView addSubview:addPhotoButton]; + + self.textView.inputAccessoryView = self.textAccessoryView; + + self.photoScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; + self.photoScrollView.scrollEnabled = YES; + self.photoScrollView.bounces = YES; + self.photoScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + + + [self.contentViewContainer addSubview:self.photoScrollView]; + + } - (void)viewWillAppear:(BOOL)animated { @@ -178,7 +216,7 @@ [[UIApplication sharedApplication] setStatusBarStyle:(self.navigationController.navigationBar.barStyle == UIBarStyleDefault) ? UIStatusBarStyleDefault : UIStatusBarStyleBlackOpaque]; #endif - [self.textView setFrame:self.view.frame]; + // [self.textView setFrame:self.view.frame]; if (_text) { self.textView.text = _text; @@ -218,6 +256,69 @@ [super viewDidDisappear:animated]; } +-(void)refreshPhotoScrollview { + CGFloat scrollViewWidth = 0; + + if (self.photos.count){ + scrollViewWidth = 100; + } + + CGRect textViewFrame = self.textView.frame; + + CGRect scrollViewFrame = self.photoScrollView.frame; + + BOOL alreadySetup = CGRectGetWidth(scrollViewFrame) == scrollViewWidth; + + if (!alreadySetup){ + textViewFrame.size.width -= scrollViewWidth; + + // status bar? + + scrollViewFrame = CGRectMake(CGRectGetMaxX(textViewFrame), self.view.frame.origin.y, scrollViewWidth, CGRectGetHeight(textViewFrame)); + self.textView.frame = textViewFrame; + self.photoScrollView.frame = scrollViewFrame; + self.photoScrollView.contentInset = self.textView.contentInset; + } + + for (UIView *subview in self.photoScrollView.subviews){ + [subview removeFromSuperview]; + } + + if (self.photos.count > self.photoScrollViewImageViews.count){ + NSInteger numberOfViewsToCreate = self.photos.count - self.photoScrollViewImageViews.count; + for (int i = 0;iINyI0iW-~k|Lo>1XIWv&31>&1P{1u3$7^n+)n2Is#^nX$;2!R^XfJLqWDi?w)qM3+@sH0Fi6pLIani{P6fTn;L3#_5^YAkZA(bQl7 z79uS02jVqAJPR#YRwIe|<1>Jo$rJ;l`#=UqAqO%<1)7PDA_WV`<Fbobk21Yt?*O8Gi z90Mct2|_0Z7I=g_0p$sJgtTKP;0Z!Ure^HcjNR(78TiI2N)1>;c1+_X!{X9GwcqwU{GGA2NtL`0jvn8%2J_(6?$5`95I4&^M@qyo~8j zz?I-Tht6vSc$bdtBJqRMF7W`NTXm8ZC=1t6MH($KY<8OQIbaItHJN-`wK)S`06$Il ze42a#E`V81-7(;Vju1-emAmR=(wXD~IXD;zBU|#f9hl`H9pKtDolj`QKEnt}{FSsI zOVt3k;GKL1j5CN+BgVK!Cl}4w8@D~+5Z~ljx5+SoO0Nv^v4*%T!6BZ~>WLj{%JT+w zs4~@jXIcjNKyw1hBYcfXs`g52eCHW-j4;NBh$S~+ZM}Xb9*+oVUBee)%qL0?#Kfo( zC0w-UPvm)PAg&s)HR$?xKW|et=&j4TKQZVkojmnspE+MmUQsuBu86$rizc5iy(hTd zE}HzDJahga91XfkC-0NzouxO0rXBaIChrlC$3`GQ_n`o#bx@M3z-!t~76jUjx~t zO9`QfTmz|2KTnu&$ls^*)Epx`P4iXy1-uo%KDuRkri%YINt?+BE#-c6u{nBd*$(_& c_