Presenting a XIB View Freezes - ios

In storyboard I have a button on my Main Menu called showCountdownViewControllerPressed.
This button is supposed to show my XIB called TimerViewController.
But when I run the app, it freezes upon button press and then after a little while crashes the app.
I put this action in my CRViewController.m (my main menu) [I also have imported the TimerViewController.h in this file]
- (IBAction)showCountdownViewControllerPressed:(id)sender {
NSLog(#"showTimerViewController");
TimerViewController *timeController = [[TimerViewController alloc]
initWithNibName:#"TimerViewController" bundle:nil];
[self presentViewController:timeController animated:YES completion:nil];

That's not the answer to your problem but it can help. I'm putting it here because I can't add images on the comments. You can put an exception breakpoint at the bottom of the breakpoints tab, normally it will stop just before the crash and you will get more info about it.
Post where the exception breakpoint it's stopping for getting more help :)

Well, if it is LandScape only, you can add this in TimerViewController for iOS 8, which will make the TimerViewController rotate to the landscape mode.
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}

Related

iOS 7: Keyboard not showing after leaving modal ViewController

I've got a HomeViewController that has different modal segues to several other UIViewControllers. If I try to show the keyboard on a UITextField within the HomeView, everything works fine. However, if I try to show the keyboard on a UITextField (using becomeFirstResponder) after returning from any of the modal View Controllers, the keyboard never shows.
Here's some sample code from one of the setups I've tried:
In HomeViewController:
- (void)viewDidAppear:(BOOL)animated
{
static BOOL firstTimeComplete = false;
if (!firstTimeComplete) {
firstTimeComplete = true;
} else {
UITextField *textField = [[UITextField alloc] init];
[self.view addSubview:textField];
[textField performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:3]
}
}
In ModalViewController:
- (IBAction)done:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Where done: is linked to the "Done" button via a touch up inside event.
A few things I've tried:
Converting the modal segues to push segues fixes the issue, but I don't want a Nav bar in any of the child views
I've tried disabling and enabling animations when dismissing the
modal view controller (using dismissViewControllerAnimated:)
Using unwind segues in the storyboard rather than doing it programmatically
Anyone have an idea of what may be going on?
After deleting tons of code, I finally found out that a custom NavigationController was being used and this was the root cause:
#implementation MSLNavigationController
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
#end
The app doesn't need this code, so I've nuked the file. (But an explanation as to why this would be hiding the keyboard would be awesome :))
You did not call [super viewDidAppear:animated]
In place like that i have workaround that works pretty well
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
if (self.textView.text.isNotEmpty)
{
[self.textView becomeFirstResponder];
}
});
}
I have been struggling with this problem for some time, so I'll post here what I found out.
I was calling textField.becomeFirstResponder() in viewWillAppear but on iOS 7, after the modal was dismissed, the keyboard would not show again, even when you would tap on the textField.
For me calling textField.resignFirstResponder() when the modal is presented, solved the issue. It seems like the input field was already marked as first responder and then would not react to the new calls.

Tab bar background is missing on iOS 7.1 after presenting and dismissing a view controller

I've tried my app on iOS 7.1 and I found that the tab bar background disappears on a few occasions. I was able to track them down; it happens when:
pushing a view controller placed inside navigation controller (that is inside tab bar controller) with hidesBottomBarWhenPushed = YES
presenting a view controller and then dismissing it (i.e. the MFMailComposeViewController)
I've created a sample app (used the tab bar template + added button to display the view controller, and a mapView to be able to tell if the bar disappeared), and the issue is there.
Here is all the code for the sample app that I changed:
#import "FirstViewController.h"
#import MessageUI;
#interface FirstViewController () <MFMailComposeViewControllerDelegate>
#end
#implementation FirstViewController
- (IBAction)presentVCButtonPressed:(id)sender {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Feedback for Routie"];
[mailer setToRecipients:#[#"support#routieapp.com"]];
[self presentViewController:mailer animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Here you can download the whole sample project.
Now, important thing: this seems not to affect iPhone 5, nor the simulator. The problem is on iPhone 4 and iPod Touch (last generation as of writing this post).
Does any of you have the same problem? Were you able to fix it?
Thanks!
Update: I found a workaround. See my answer below.
Fix found!
So after some investigating (and headache), I found out that there is a simple fix. Just toggle the translucent property, like this:
tabBar.translucent = NO;
tabBar.translucent = YES;
Now as for when to do this, there are several places for each case:
1) pushing viewController with hidesBottomBarWhenPushed = YESThe bar background disappears right after the pop animation finishes, so add the fix to the viewDidAppear: method of the viewController that presented it:
- (void)viewDidAppear:(BOOL)animated {
self.navigationController.tabBarController.tabBar.translucent = NO;
self.navigationController.tabBarController.tabBar.translucent = YES;
...
}
2) Presenting a view controller and then dismissing it:In this case, the tab bar background is already gone during the dismiss animation. You can either do it in each viewController that you present separately, or, if you have subclassed UITabBarController (like I have), you can add it into its viewWillAppear method. Just be aware that calling the fix right away won't help (I've tried); that's why I used the dispatch_after GCD function:
- (void)viewWillAppear:(BOOL)animated {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tabBar.translucent = NO;
self.tabBar.translucent = YES;
});
...
}
I know this is not the cleanest way, but it's clearly bug on Apple's side, and it's likely to stay with us for a while (I assume there won't be any iOS 7.2, so we'll most likely be stuck with this until iOS 8 comes out).
It's been a while, so I'll re-iterate the issue. iOS 7 (on Device) Tab Bar becomes completely see-through on device, but works fine on Simulator. Appears to happen after hitting Back from a detail page that has hidesBottomBarWhenPushed enabled.
Setting the Tab Bar Controller > Tab Bar > Background to White Color in the Storyboard fixed it for me. This fix keeps the translucency intact.
For some reason, toggling tabBar.translucent off and on again in ViewDidAppear did not work for me.
Using Xcode 6.3.1 with Swift.
Go in your Main.storyboard and select your MKMapView to highlighted it (cf. in Navigator area you can select « Map View »). Then look carefully where is the bottom "white square": move it up the bottom bar!
In the size inspector, you can check where you place the « anchor » or view origin for this view (cf. top-left hand side in your project). This explains why it’s ok for iphone 5 which has a bigger height screen.

After forcing an orientation of an IOS 7 app to Portrait, nothing on the screen becomes tappable

I am seeing an issue that only happens on IOS 7 and not IOS 6, i.e. the same code works on 6 but not 7.
Basically, there is this view that I need to transition to that must be in portrait mode.
So, like many of the other examples I found on StackOverflow, the way to force an orientation would be to call this on the navigation controller :
UIViewController *mvc = [[UIViewController alloc] init];
[self presentViewController:mvc animated:NO completion:^{
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Cleared");
[mvc.view removeFromSuperview];
[mvc removeFromParentViewController];
}];
}];
And in the target controller, I have:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
However, once I transition to this target UIViewController, nothing on that UIViewController becomes tappable at all. I am very sure that the UIButtons are linked properly because if I just load up this controller as the first controller when the app starts, the buttons all worked fine, but if I have to force an orientation on it before showing it, then the buttons don't work
I was wondering if anyone else has encountered such an issue in IOS 7 as well? This works perfectly in IOS 6
Thanks
IS

Display the master view controller of UISplitViewController in portrait and landscape mode for a specific view

I am trying to implement a hide/unhide feature for the master view controller of my UISplitViewController. So the master view controller should be present in portrait and landscape mode but just for a specific view (the settings). Everywhere else it should appear in landscape only.
In -(void)viewDidAppear:(BOOL)animated of my MasterController I am writing
self.popoverController.delegate = self;
appDelegate.splitViewController.delegate= nil;
appDelegate.splitViewController.delegate = self;
[appDelegate.splitViewController willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
[appDelegate.splitViewController didRotateFromInterfaceOrientation:self.interfaceOrientation];
appDelegate.splitViewController.view setNeedsLayout];
The delegate method is also set
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
This approach I found here on stackoverflow really works well, but just as long as I rotate the device. Then the master view controller disappears (and leaves a black space). While rotating it appears and as soon as the rotation is done it disappears again. Further the master view controller disappears complelty if I click outside.
So I implemented the following delegate method to prevent the popover from disappearing
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
That works too, but then the tableView of my detail view is not responding.
If I delete the code from -(void)viewDidAppear:(BOOL)animated and the UIPopoverControllerDelegate method, it works all as expected, but just after I rotate the device.
So my question is, if anyone has an idea how I can solve that problem. The solution should be able to work with iOS 5.0 and newer.
Thanks a lot for your answers!

UIImagePickerController in iOS 6 doesn't work properly

I'm having a very strange behavior:
in iOS 5 I present UIImagePickerController in this way:
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
imagePicker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:imagePicker animated:YES];
now in iOS 6 this produce a crash. I resolved the crash by writing a category on UIImagePickerController:
#implementation UIImagePickerController (NonRotating)
- (BOOL)shouldAutorotate
{
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#end
The problem is that now the UIImagePickerController doesn't rotate and it's shown up-side. Moreover, when I press the "cancel" button and the picker is dismissed, the app crash again.
If I use the UIImagePickerController inside a UIPopoverController, all works fine (belonging to the fact that the popover doesn't rotate) but when I dismiss the popover ALL view controller in my app stop responding to rotation events and this cause that all app is blocked in this orientation. To restore the correct behavior I need to quit the app from the background and open again.
This is the code I'm using to display popover
_cameraPopoverController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[_cameraPopoverController presentPopoverFromRect:_takeFromCamera.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
This problem drive me crazy !
What is your picker source type?
Photo library/album or camera roll?
Assuming that you are using Photo Library / Album source, on iPad, you MUST use a popover:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html (look in the overview, point 4)
presenting it fullscreen is not supported.
About the other issue (after dismissing the popOver, the other VC's stops rotating) check that you have a STRONG reference to your popover (strong property).
Paste the code you are using to present the popover.
While I don't recommend using the category to override the image picker's default behavior, there is a bug in the implementation that causes the crash mentioned:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
~~~~
}
The return value shouldn't be an orientation mask, it should be an orientation, e.g. UIInterfaceOrientationPortrait.

Resources