UIActivityViewController presenting issue iphone - objective-c

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:#[message] applicationActivities:nil];
activityVC.excludedActivityTypes = nil;
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed)
{
activityVC.completionHandler = nil;
// if (completed)
// [Utils alertMessage:kNSLocalizedString(#"TITLE20_KEY#0", nil) title:nil delegate:nil cancelButton:kNSLocalizedString(#"OK_KEY#0", nil) otherButton:nil hiden:nil];
[activityVC dismissViewControllerAnimated:YES completion:^{
_isSharing = NO;
}];
}];
if ([self respondsToSelector:#selector(popoverPresentationController)]) {
activityVC.popoverPresentationController.sourceView = self.view;
}
[self presentViewController:activityVC animated:YES completion:^{
_isSharing = YES;
}];
I am getting the below warning.
Warning: Attempt to present
on which is already presenting (null)

Check for your Viewcontroller as its giving self as null.
You can check tutorial for UIActivityViewController from below link
http://www.amaniphoneblog.com/2014/09/uiactivityviewcontroller-ios-tutorial.html

Use this method to call the function contains presenting UIActivityViewController
[self performSelector: #selector(urMethodToPresentActivityController) withObject: nil afterDelay: 0.1];`

Related

Check if user shares with Twitter

I am using an UIActivityViewController to show my share-dialogue.
How can I check if the user is using Twitter/Facebook/etc.?
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
UIPopoverPresentationController *presentationController = [activityViewController popoverPresentationController];
[self presentViewController:activityViewController animated:YES completion:nil];
I want to customize the Text for sharing with different services, so this would be really helpful.
You can use setCompletionWithItemsHandler like this:
UPDATE - remove the if(complete)
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
[activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError)
{
//if (completed)
//{
if ([activityType isEqualToString:UIActivityTypeMail]) {
//code for email
} else if ([activityType isEqualToString:UIActivityTypeMessage]) {
//code for iMessage
} else if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
//code for Facebook
} else if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
//code for twitter
}
//}
}];
UIPopoverPresentationController *presentationController = [activityViewController popoverPresentationController];
[self presentViewController:activityViewController animated:YES completion:nil];

From Login screen to `UITabBarController`

I have a Login screen which checks if the inserted Password is correct.
After that I want to switch from the Login screen to a UITabBarController.
Code from LoginViewController.m:
-(IBAction)LoginButton:(id)sender {
[PassWortEingabe resignFirstResponder];
NSString *pnssPasswortEingabe = [NSString stringWithFormat:#"%#",PassWortEingabe.text];
NSString *pnssPasswortString = [NSString stringWithFormat:#"%s","Hallo"];
if( [pnssPasswortEingabe isEqualToString: pnssPasswortString ]){
DebugTextView.text = #"Login succesfull";
//PassWortEingabe = 0;
//[PassWortEingabe resignFirstResponder];
}else{
DebugTextView.text = #"Login unsuccesfull";
//PassWortEingabe = 0;
//[PassWortEingabe resignFirstResponder];
}
}
I want jump to the UITabBarController when the Login is sucessful ...
if( [pnssPasswortEingabe isEqualToString: pnssPasswortString ]){
DebugTextView.text = #"Login succesfull";
MyTabBarClass *myTabBar = [[MyTabBarClass alloc]initWithNibName:nil bundle:nil];
myTabBar.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:myTabBar animated:YES];
//PassWortEingabe = 0;
//[PassWortEingabe resignFirstResponder];
}else{
DebugTextView.text = #"Login unsuccesfull";
//PassWortEingabe = 0;
//[PassWortEingabe resignFirstResponder];
}
It is as simple as the code below.
if( [pnssPasswortEingabe isEqualToString: pnssPasswortString ]){
// This is for iOS 5.0 and above.
UITabBarController *myTabBarController = [self.storyboard instantiateViewControllerWithIdentifier:#"myTabBarController"];
[myTabBarController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:myTabBarController animated:YES completion:^(void){
// You can set some sort of completion block here which will run when all other code finishes, this can just be nil.
}];
} else {
DebugTextView.text = #"Login unsuccesfull";
}
You can also replace this line with
[self presentViewController:myTabBarController animated:YES completion:nil];
replace with
[self presentModalViewController:myTabBarController animated:YES];
but this has been deprecated in iOS 6.0. So if you are making your app for iOS 5.0 and above you are best of using the first line so you don't have to make changes in the future.
The above code is made to use storyboards if you want to do it with nib files then change
[self.storyboard instantiateViewControllerWithIdentifier:#"myTabBarController"];
to
[[UITabBarController alloc] initWithNibName:#"myTabBarController" bundle:[NSBundle mainBundle]];
Hope this helps.

iOS: Image Will Not Delete From Array

I'm working on an app that behaves like a photo gallery, and I'm implementing the option to have the user delete photos from their gallery. To accomplish this, I decided to place an invisible button over each picture. When the user hits an "Edit" button, the hidden delete buttons over each picture become active. I'm using the same IBOutlet over each of the hidden buttons for simplicity, and I've tagged each button appropriately in Interface Builder. When the user taps the button over the picture, an alert view appears asking if they really want to delete it. If they click yes, I call removeObjectAtIndex. Here is the code I'm using:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
The issue here is that when I click "Yes" in the alert view, nothing happens. However, if I tap on the image and click "Yes" a second time, the app crashes, and the debug states:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray removeObjectAtIndex:]: index (0) beyond bounds (0)' So, I'm not sure where to go from here, I'm still very new to programming and everything looks correct to me. Any help is much appreciated, thanks!
Here is how I add them into the array:
////start of saving////
- (void)viewWillAppear:(BOOL)animated
{
self.user = [NSUserDefaults standardUserDefaults];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
while(self.array == nil)
{
[self.user setObject:[NSMutableArray arrayWithObject:#""] forKey:#"images"];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
NSLog(#"%#",#"attempting to create an array to store the images in");
}
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSLog(#"Image on didenterbackground: %#", imageView);
self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView5.image)]];
[self.user setObject:self.array forKey:#"images"];
[user synchronize];
}
- (void)viewDidLoad
{
self.user = [NSUserDefaults standardUserDefaults];
NSLog(#"It is %#", self.user);
self.array = [[self.user objectForKey:#"images"]mutableCopy];
imageView.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:0]];
imageView2.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:1]];
imageView3.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:2]];
imageView4.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:3]];
imageView5.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:4]];
imageView6.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:5]];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
backToGalleryButton.hidden = YES;
tapToDeleteLabel.hidden = YES;
deleteButton1.hidden = YES;
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.user = nil;
}
////end of saving
///// shows the hidden and invisible "delete" button over each photo.
- (IBAction)editButtonPressed:(id)sender {
grabButton.hidden = YES;
editButton.hidden = YES;
backToGalleryButton.hidden = NO;
tapToDeleteLabel.hidden = NO;
deleteButton1.hidden = NO;
}
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
NSLog(#"Array: %#, index: %d", self.array, alertView.tag);
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
#end
EDIT: This is the code I use to put the objects into the UIImageView from the users camera roll:
- (IBAction)grabImage {
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
_popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
[_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentModalViewController:imgPicker animated:YES];
}
[self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView2.image == nil) {
imageView2.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView3.image == nil) {
imageView3.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView4.image == nil) {
imageView4.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
}
When I added NSLog(#"Array: %#, index: %d", self.array, alertView.tag); just before removeAtIndex the console says 2012-04-03 18:39:39.066 AppName[1631:f803] Array: (null), index: 0. Could that be the cause? I'm not sure why it would be, I think the code looks fine.
Removing the image from the array is not the only step you have to take. Your code is correct for removing the image from the array, which is why you get image out of bounds the second time, but you also need to remove the image from the UI so the user can no longer delete an image that is not there.
There are many oddities with this code but I think the problem is that you are not calling super on your viewwillappear and viewdidload functions. I would get rid of your viewWillAppear method as it serves no purpose.

-initWithContentsOfFile: for an NSMutableArray

I stored images in an NSMutableArray, and now I'm trying to get them to show up in viewDidLoad. I tried calling initWithContentsOfFile, but that doesn't seem to work. This is how the code looks:
imageView.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:0]];
I'm not sure what I should use instead of initWithContentsOfFile to have the saved images load, I'm not even sure if I can save images in a plist through user defaults. I've been researching it for awhile now to no avail. Any help is much appreciated, thanks!
EDIT: Here is additional code:
- (IBAction)grabImage {
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
_popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
[_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentModalViewController:imgPicker animated:YES];
}
[self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[self.array addObject:imageView.image];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView2.image == nil) {
imageView2.image = img;
NSLog(#"The image is a %#", imageView);
[self.array addObject:imageView2.image];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView3.image == nil) {
imageView3.image = img;
[self.array addObject:imageView3.image];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSLog(#"Image on didenterbackground: %#", imageView);
[self.array addObject:imageView.image];
[self.array addObject:imageView2.image];
[self.array addObject:imageView3.image];
[self.user setObject:self.array forKey:#"images"];
[user synchronize];
}
- (void)viewDidLoad
{
self.user = [NSUserDefaults standardUserDefaults];
NSLog(#"It is %#", self.user);
self.array = [[self.user objectForKey:#"images"]mutableCopy];
imageView.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:0]];
imageView2.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:1]];
imageView3.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:2]];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
backToGalleryButton.hidden = YES;
tapToDeleteLabel.hidden = YES;
deleteButton1.hidden = YES;
[super viewDidLoad];
}
EDIT: This is how I'm tagging the images and deleting them based upon their tags:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (UIImageView *)viewForTag:(NSInteger)tag {
UIImageView *found = nil;
for (UIImageView *view in self.array) {
if (tag == view.tag) {
found = view;
break;
}
}
return found;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
NSLog(#"The tag is %i", alertView.tag);
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
}
NSLog(#"After deleting item, array count = %d", [array count]);
NSLog(#"Returned view is :%#, in view: %#", [self.view viewWithTag:alertView.tag], self.view);
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:#"images"];
}
The problem is that you can't store images in a property list, which is what you're trying to do when you save it in the user defaults. You need to use an archiver to convert the image to an NSData object which you can store.
It looks like you're not passing a valid image path to the initializer method. Make sure the path is correct, and that it includes the image extension.
Really, though, you shouldn't be calling initWithContentsOfFile: in this case, because UIImageView's image property retains the image when you set it. That will usually lead to a memory leak (unless you're using automatic reference counting). Use one of the static initializers instead, such as imageNamed:, which has the added bonuses of using the system cache and also automatically loading the correct version of the image based on the characteristics of the device (for instance, it will load a higher resolution variant of the image if the device has a retina display).

Getting a SIGABRT error in dismissModalViewController

Im receiving a SIGABRT error when I cancel a MFMailComposeViewController, exactly in the dismissViewController, don't work
I have a UIViewController within a UINavigationController.
My Code:
- (void)sendMail {
if ([MFMailComposeViewController canSendMail]) {
controller = [[MFMailComposeViewController alloc] init];
[[controller navigationBar] setTintColor:[UIColor getHexColorWithRGB:#"e2de09" alpha:1.0f]];
controller.mailComposeDelegate = self;
[controller setSubject:#"Subject"];
NSString *msg="xxxxx";
[controller setMessageBody:msg isHTML:YES];
[self presentModalViewController:controller animated:YES];
} else {
NSString * errorString = [NSString stringWithFormat:#"mail account not set."];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error:" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
The presentModalViewController:animated: works correctly.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self becomeFirstResponder];
[self dismissModalViewControllerAnimated:YES];
}
But calling [self dissmissModalViewControllerAnimatedLYES] causes a SIGABRT error.
I think the "dismissModalViewControllerAnimated" should be called on the MFMailComposer object, in your case "controller". Note that it is in fact a view controller.
It's resolved!
I had a viewWillDisappear: method where I was removing views...
This method was being called before of present the ModalView and my ViewController was over released on dissmissModalViewController.
I have changed this method.
Thanks