iOS7 sending SMS from inside the app has a misaligned modal view - objective-c

I'm writing an app where I need to allow the user sending SMS from within the app.
It works fine on iOS6 but not on iOS7.
When I'm trying to send a text message, the modal view appears but there is a strange gap between the "to" field and the list of possible contacts.
After selecting the first contact, the "to" field slides up and disappears and then I see past messages and my new message but with the same gap again.
I'm attaching two images showing the issue:
Here is the code I'm using:
if([MFMessageComposeViewController canSendText]) {
NSArray *recipents = nil;
NSString *message = #"Let's go";
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipents];
[messageController setBody:message];
[self presentModalViewController:messageController animated:YES];
}
Please tell me if know you know how to fix this issue.
Thanks!
Additional info:
This bug only happens in iOS 7.x not in in iOS 6.x
Also, if I use the MFMailComposeViewControllerDelegate to send emails, it works just fine (although they are both implemented by MessageUI.h)...

Ok, I figured it out.
The issue happens because I have a custom UINavigationController.
In my AppDelegate, I had the following code:
UIImage *navBarImage = [UIImage imageNamed:#"BarIos7.png"];
[[UINavigationBar appearance] setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault];
Once I removed it, everything started working fine.

Related

ios 8 : ABPeoplePickerNavigationController dismiss on implementing people picker delegate methods

This is strange behavior noticed while accessing contact details from address book in ios 8.
My scenario is simple
Show contacts table
select a row that will invoke didSelectPerson method
in didSelectPerson method
push SecondViewController
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person;
{
SecondViewController *detailVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[detailVC.view setBackgroundColor: [UIColor redColor]];
// [peoplePicker.navigationController pushViewController:detailVC animated:YES];
[peoplePicker pushViewController:detailVC animated:YES];
}
but what happens is ABPeoplePickerNavigationController dismiss.
Please enlighten me on this.
I don't know the philosophy thing what happens under the hood of the "didSelectPerson" method, me was facing the same problem today. I found a simple solution to overcome this issue, i override the
"-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion" method of the "ABPeoplePickerNavigationController". Then implement it like somewhat following
bool dismissedEnabled;
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
if (dismissedEnabled) {
[super dismissViewControllerAnimated:flag completion:completion];
}
}
then inside the "didSelectPerson" i have done the following
viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:[NSBundle mainBundle]];
dismissedEnabled = false;
[self presentViewController:viewController animated:YES completion:nil];
this works for me, hope you guys overcome it too :)
It automatically dismisses if you select a contact with a single email address for example.
If a contact has more than one email, you must specify a predicate that will force the ABPeoplePickerNavigationController to push a ABPersonViewController on the stack.
if ([picker respondsToSelector:#selector(setPredicateForSelectionOfPerson:)])
{
// The people picker will select a person that has exactly one email address and call peoplePickerNavigationController:didSelectPerson:,
// otherwise the people picker will present an ABPersonViewController for the user to pick one of the email addresses.
picker.predicateForSelectionOfPerson = [NSPredicate predicateWithFormat:#"emailAddresses.#count = 1"];
}
I believe the default behavior in iOS 8 is that the ABPeoplePickerNavigationController is automatically dismissed when didSelectPerson is called.
The reason that the SecondViewController is not displayed (I'm inferring that this is the problem symptom) is because you are trying to push the SecondViewController while the ABPeoplePickerNavigationController is being dismissed. This overlapping animation is a problem that the iOS core view management/animation system tries to avoid.
You may get a warning in the console when this happens.
#Ratul's solution works because it circumvents this default behavior.
In my scenario, my code sleeps a second before presenting a UIAlertController from within didSelectPerson. This is a hack that depends on the ABPeoplePickerNavigationController dismissal animation taking less than a second. For me, if this alert is not displayed, nobody would even notice this was a problem.
If you want something more robust, you may want to override viewDidAppear to handle this special case (using a flag in your presenting view controller). But this gets a bit clumsy as well.

Application tried to push a nil view controller on target <MFMessageComposeViewController: 0x96d1380>

Has anybody encountered this kind of error in MFMessageComposeViewController?
I allocated and presented it like this:
MFMessageComposeViewController *message = [[MFMessageComposeViewController alloc] init];
message.messageComposeDelegate = self;
[[UIApplication sharedApplication].delegate.window.rootViewController presentModalViewController:message animated:YES];
but it presents an empty view and says:
Application tried to push a nil view controller on target <MFMessageComposeViewController: 0x96d1380>.
Possible duplicate of MFMessageComposeViewController on Simulator - canSendText?
Basically this occurs in the simulator on Lion and Mountain Lion if it has a Messages account enabled. Try testing on a real device as it should work okay there.

IOS FacebooSDK 3.0 FBLoginVIew in modal viewController

I have modal view controller displayed on rightBarButtonItem click. I'm using FbLoginView in this controller as in sample ios-Facebook SDK 3.0 Error 5 When Posting Status Update.
But i'm unable to show modal view controller more than one time.
I tried to release FBLoginView on ViewDidUnload but it always crashes on second atempt to open modal view controller.
Got the same problem and deal with it for couple days already. And finally this is my solution:
if (!FBSession.activeSession.isOpen) {
theLoginView = [[FBLoginView alloc] init];
theLoginView.frame = CGRectOffset(theLoginView.frame,
([[UIScreen mainScreen] bounds].size.width-theLoginView.frame.size.width)/2,
([[UIScreen mainScreen] bounds].size.height-theLoginView.frame.size.height)/2 -50);
theLoginView.delegate = self;
[self.view addSubview:theLoginView];
[theLoginView sizeToFit];
}
//Only close the session when application is terminating, this will save the token information:
- (void)applicationWillTerminate:(UIApplication *)application {
[FBSession.activeSession close];
}
//And keep the FBSession within the app until the user want to logout:
[FBSession.activeSession closeAndClearTokenInformation];
Right now for me its working completely fine. Hope this help.
The FB SDK doesn't seem to like you creating more than one FBLoginView. Maybe you can if you properly terminate the session, but I found it easier just to create the LoginView once and keep it around.
I did this as follows:
1) in my .m modal view controller file, I created a static variable
static FBLoginView* loginView;
2) When loading the modal view controller in my viewDidLoad, instead of
FBLoginView *loginview = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginview.frame = CGRectOffset(loginview.frame, 10, 10);
I added a check to find if its already initialized, like this:
if (!loginView) {
loginView = [[FBLoginView alloc] initWithPermissions:
[NSArray arrayWithObject:#"status_update"]];
loginView.frame = CGRectOffset(loginView.frame, 10, 10);
}
Beyond that, I just followed the example of FB's HelloFacebook project.
Not pretty code, but it seems to work.
I had the same problem. Try to add something like this:
if(!yourFBLoginView)
{
yourFBLoginView = [FBLoginView alloc] init...];
}
And/or do not forget to close your active session when you dismissing your modalViewController.
if ([[FBSession activeSession] isOpen])
{
[[FBSession activeSession] close];
}
I think the answer for me (a variant of what was said) was only that I needed to have:
[FBSession.activeSession closeAndClearTokenInformation];
in the:
(void)applicationWillTerminate:(UIApplication *)application
function. The problem specifically for me was, while I was testing...I was constantly terminating the app without actually logging out the user without ever destroying the FBSession, so that when I went back into the app to test what I had changed - my Facebook user was still logged in, and thus some of the conditionals were being incorrectly met. I think this is very important for anyone who is testing (and I'm actually thinking that you should have that line in there anyway) to make sure to clear the session every time the application terminates to avoid this problem...I can imagine a scenario where my app just crashed on somebody and now they are reopening it and they experience the crash because the session was never cleared.

How to handle mountain lion notifications clicks

I just wanted to add some notifications to Gyazo app.
I finally able to send notifications to the notifications center http://korniltsev.ru/p/jz6m3Nm.png
however when i click on it and the app is not launched it launches in some strange way:
it shows empty window(even if i set it visibleAtLaunch to 0) and nothing happens;http://korniltsev.ru/p/jz6mvk0.png
the code i'm trying to use is here:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSUserNotification * clicked = [[aNotification userInfo]
objectForKey:NSApplicationLaunchUserNotificationKey];
if (clicked){
[NSApp terminate:self];
return;
}
...
I send notifications like this
NSUserNotificationCenter *manager = [NSUserNotificationCenter defaultUserNotificationCenter];
NSUserNotification *urlNotification = [[NSUserNotification alloc]init];
[urlNotification setTitle:appName];
[urlNotification setInformativeText:url];
[manager deliverNotification:urlNotification];
What am i doing wrong?
[NSApp terminate:self] has a lot of side effects. Are you sure these side effects are not creating your blank window? Have you tried calling [NSApp terminate:self] immediately in applicationDidFinishLaunching and making sure you application quits cleanly in every case? If it does not you will likely have to look at what you are doing in your application's document controller (if you have one) and applicationShouldTerminate.

UIDocumentInteractionController: "Open In" visible on iPhone but not on iPad - why?

For testing purposes I wrote two apps:
First one plays an MP3 file using UIDocumentInteractionController
Second one does nothing but registers for the file type "public.mp3"
If I deploy the apps to the iPhone Simulator, my MP3 player app shows a button on top "Open in 'MP3Test'". If I deploy to the iPad Simulator however, there is no button and no "Open In" menu either.
This has been tested with iOS5.
Can somebody explain if this is a bug or a feature and what the reason is behind it?
Depends upon where you are presenting it from.
If you are presenting it from somewhere around the middle of the screen or below, just present from the frame of the object that you are presenting from.
if that is on the navigation bar, try this:
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"License" ofType:#"pdf"];
UIDocumentInteractionController *controller = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
controller.delegate = self;
CGRect navRect = self.navigationController.navigationBar.frame;
navRect.size = CGSizeMake(1500.0f, 40.0f);
[controller presentOptionsMenuFromRect:navRect inView:self.view animated:YES];
The iPad has an affinity for popovers (see UIPopover), why it presents UIActionSheets in them. Facing a similar issue that you had, I had my UIDocumentInteractionController present itself from an UIBarButtonItem (resulting in a UIPopover presentation), rather than from the view itself (something that worked just fine on the iPhone):
Save a reference to the action button (I have mine in my navigation bar).
Use PresentOpenInMenu using the action button reference, rather than the View reference, resulting in a UIPopover-presentation.
Please note that the change does not effect the iPhone app - it behaves likes before, i.e. opens the OpenInMenu from the bottom of the screen just as it would, if you'd used the View reference to present it.
On iPad UIDocumentInteractionController appearing like Pop Up Try something like this
-(void)shareClick:(UIButton*)sender {
/*some code*/
CGRect rectFor appearing = [sender.superview convertRect:sender.frame toView:self.view];
[interactionController presentOptionsMenuFromRect:rect inView:self.view animated:YES];
}