Callback strong Reference Cycle - objective-c

Is the following creating a strong reference cycle? I have a feeling it is because I'm referencing self within callback.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:^{
UIImage *image = [self cropImageWithInfo:info];
if (currentScreen == CurrentScreenApartment) {
[self.profileViewModel.apartmentPhotos addObject:[RuntimePhoto runtimePhotoWithImage:image]];
}
else {
[self.profileViewModel.userPhotos addObject:[RuntimePhoto runtimePhotoWithImage:image]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self reloadPhotosCell];
});
}];
}

You can use a weak variable of self:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
typeof(self) __weak weakSelf = self;
[picker dismissViewControllerAnimated:YES completion:^{
UIImage *image = [weakSelf cropImageWithInfo:info];
if (currentScreen == CurrentScreenApartment) {
[weakSelf.profileViewModel.apartmentPhotos addObject:[RuntimePhoto runtimePhotoWithImage:image]];
}
else {
[weakSelf.profileViewModel.userPhotos addObject:[RuntimePhoto runtimePhotoWithImage:image]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf reloadPhotosCell];
});
}];
}

Related

iOS7 UISearchDisplayController bug with Navigation Bar not automatically hidden

Reveal shows the following:
-> UINavigationBar
-> UINavigationTransitionView
->UITableView
->UISearchDisplayController
->UISearchBar
When I hit the searchBar the searchDisplayController does not hide the NavigationBar instead it reveals half of it.
I do not use auto layout (so not constraints), I am using a UITableViewController, I cannot use the new UISearchController and I am looking for a solution to either make it work as it should or either do not allow it to expand. The problem occurs only for the iPad. The project supports iOS7 and above.
I am trying to catch everything in the following methods:
#pragma mark - UISearchDisplayController Delegate
- (void)searchDisplayController:(UISearchDisplayController *)controller willHideSearchResultsTableView:(UITableView *)tableView {
self.onlineSearchRequestUUID = [NSUUID UUID];
dispatch_async(self.searchSerialQueue, ^{
if ([self.parentVC needsEmail]) {
self.capiContact->setFilter(CAPIContactFilter::WithEmail, "");
} else {
self.capiContact->setFilter(CAPIContactFilter::All, "");
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.parentVC.tableView reloadData];
});
});
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
dispatch_async(self.searchSerialQueue, ^{
[self filterContentForSearchText:searchString
scope:[controller.searchBar scopeButtonTitles][[controller.searchBar selectedScopeButtonIndex]]];
dispatch_async(dispatch_get_main_queue(), ^{
[controller.searchResultsTableView reloadData];
if ([searchString length] == 0) {
[self.parentVC.tableView reloadData];
}
});
});
return NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
dispatch_async(self.searchSerialQueue, ^{
[self filterContentForSearchText:[controller.searchBar text]
scope:[controller.searchBar scopeButtonTitles][searchOption]];
dispatch_async(dispatch_get_main_queue(), ^{
[controller.searchResultsTableView reloadData];
});
});
return NO;
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
if (![self.tableView isEditing]) {
searchBar.showsScopeBar = YES;
[searchBar sizeToFit];
_oldnavCol = [self.navigationController.view.backgroundColor copy];
#try {
[self.navigationController.view setBackgroundColor:[[[[self.parentVC.searchDisplayController searchBar] subviews][0] subviews][1] barTintColor]];
}
#catch (NSException *exception) {
LogDebug(#"%#", exception);
}
return YES;
}
return NO;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
double delayInSeconds = .5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
[self.navigationController.view setBackgroundColor:_oldnavCol];
_oldnavCol = nil;
}
});
return YES;
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
//Here is where i have tried most of my tries to make it work with hacks but with no luck.
//self.navigationController.navigationBar.translucent = YES;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.searchDisplayController.searchBar.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 88);
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
self.tableSearchText = searchText;
//some code here
if ([searchText length]) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSString *uuid = [self.onlineSearchRequestUUID UUIDString];
//some more code here
});
}
}
I don't think I am missing something.
Any help would be appreciated.
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[[[parentViewController navigationController] navigationBar] setHidden: YES];
}
}
for my case parentViewController is either self or self.parentVC and it works like a charm.

UIImagePickerController delegate to different ViewController after taking Picker

I created a simple button within my Main-View Controller. After calling imagePickerController and taking a picture, I want to redirect the user to the next view controller to continue processing the image. Somehow it always returns to my main window.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
UIImage *image = info[UIImagePickerControllerOriginalImage];
_imageView.image = image;
if (_newMedia)
UIImageWriteToSavedPhotosAlbum(image,
self,
#selector(image:finishedSavingWithError:contextInfo:),
nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
// Code here to support video if enabled
}
}
for that you have to push your view Like
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
...
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
...
YourImgViewController *imgProcessing = [[YourImgViewController alloc] initWithNibName:#"YourImgViewController" bundle:nil];
imgProcessing.selectedImageView.image = image;
[self.navigationController pushViewController:imgProcessing animated:YES];
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
// Code here to support video if enabled
}
}
very simple!
you can find more hint on this link http://www.edumobile.org/iphone/how-to-make-an-app-2/tutorial-on-image-picker-controller-in-iphone/

iOS: Warning: Attempt to present <ModalViewController> on <ViewController>while a presentation is in progress

I am trying to create a modal view controller after picking an image from the image picker. I use the code :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSLog(#"Picker has returned");
[self dismissModalViewControllerAnimated:YES];
// TODO: make this all threaded?
// crop the image to the bounds provided
img = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"orig image size: %#", [[NSValue valueWithCGSize:img.size] description]);
// save the image, only if it's a newly taken image:
if([picker sourceType] == UIImagePickerControllerSourceTypeCamera){
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
}
// self.image_View.image=img;
//self.image_View.contentMode = UIViewContentModeScaleAspectFit;
ModalViewController *sampleView = [[ModalViewController alloc] init];
[self presentModalViewController:sampleView animated:YES];
}
However, I receive the warning:
Warning: Attempt to present <ModalViewController: 0x7561600> on <ViewController: 0x75a72e0> while a presentation is in progress!
and the modal view does not appear.
What am I doing wrong?
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
// TODO: make this all threaded?
// crop the image to the bounds provided
img = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"orig image size: %#", [[NSValue valueWithCGSize:img.size] description]);
// save the image, only if it's a newly taken image:
if ([picker sourceType] == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
}
// self.image_View.image = img;
// self.image_View.contentMode = UIViewContentModeScaleAspectFit;
NSLog(#"Picker has returned");
[self dismissViewControllerAnimated:YES
completion:^{
ModalViewController *sampleView = [[ModalViewController alloc] init];
[self presentModalViewController:sampleView animated:YES];
}];
}
Here the issue is happening because, you are first dismissing the UIImagePicker and immediately you are displaying another view as modal view. That's why you are getting this error.
Check with the following code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:NO completion:^{
img = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"orig image size: %#", [[NSValue valueWithCGSize:img.size] description]);
if([picker sourceType] == UIImagePickerControllerSourceTypeCamera)
{
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
}
ModalViewController *sampleView = [[ModalViewController alloc] init];
[self presentModalViewController:sampleView animated:YES];
}];
}

UIImagePicker freezes

I'm able to call the modal view controller for the image picker, pick the image, and crop it, but when I tap 'done' it doesn't do anything, it just hangs with the done button grayed out.
There are no errors, but the function is called.
- (void)viewDidLoad
{
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.allowsImageEditing = YES;
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
userImage.image = img;
uploadButton.hidden = NO;
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
NSLog(#"called");
}
- (IBAction)getImage:(id)sender {
[self presentModalViewController:self.imgPicker animated:YES];
}
Replace
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
with:
[self dismissModalViewControllerAnimated:YES];

UIimagepickercontroller

I am using UIimagepickercontroller to browse or take a photo and display it on a subview.
-(IBAction) getPhoto:(id) sender {
secondView1 = [[secondView alloc]
initWithNibName:#"secondView"
bundle:nil];
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIButton *) sender == choosePhotoBtn) {
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
} else {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:picker animated:YES];
[self.view addSubview:secondView1.view];
}
This works fine for SourceTypeSavedPhotoAlbum, but if I use camera, the secondview1.view does not show. Instead it only shows the original view.
This is my delegate method:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
secondView1.imageView.image = [info
objectForKey:#"UIImagePickerControllerOriginalImage"];
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[picker release];
}
Thank you for any help!
I finally found out that I should do:
secondView1 = [[secondView alloc]
initWithNibName:#"secondView"
bundle:nil];
self.view addSubview:secondView1.view];
in the delegate function.
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
...
}
Otherwise, the addsubview could be called before the image picker finishes picking an image. Now understand better about how the code flows and the delegate functions.