I am trying to set the frame of my superview when presenting a view, the code i used is
navigationController.modalPresentationStyle = UIModalPresentationPageSheet;
navigationController.view.superview.frame = CGRectMake(32, 20, 1024-(32*2), 748);
[[self navigationController] presentModalViewController:navigationController animated:YES];
the code was working fine in OS6. but when come to OS7 its not working.
This method has been deprecated in iOS 7.
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);
Use the following :
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);
If it was working in iOS 6 it was by chance. You are depending on the private view hierarchy used by iOS when presenting modal view controllers, and you've just found out why this is a bad idea. It can, and does, change without warning or documentation. See also, the view hierarchy of a UITableView between iOS 6 and 7.
If you want to make your own style of presented view controller it is safest to write it yourself from scratch rather than hijack one of the existing ones. Try using the custom style of presentation and writing a transition delegate.
Ok i found a solution.,
BOOL ios7 = [UIDeviceHardware isOS7Device];
if(ios7){
navigationController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
}
Now it works fine. :)
Related
I'm having a hard time with my SearchDisplayViewController on iOS 7.
I have a searchBar hidden over a UITableViewController, like
self.tableView.tableHeaderView = searchBar;
Problem is that when I tap on the searchBar to type in something, then the view starts greying out, and I quickly tap the screen in a random point to dismiss it, coming back to the tableView, the searchBar disappears. Totally. Only on iOS 7 though.
Debugging it, the frame is always the same: 0,0,320,44. But the bar is invisible!
Also tried to do
self.tableView.contentOffset = CGPointMake(0,self.searchDisplayController.searchBar.frame.size.height);
still disappears when I do it quickly.
On iOS 6 it works just fine. Problem is only with iOS 7 as far as I'm seeing.
I don't know what it depends on, has anyone encountered the same problem I have?
As of Double tap UISearchBar with search delegate on iOS 7 causes UISearchBar to disappear, I found the workaround to actually work and solved the bug - for now.
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
[self.tableView insertSubview:self.searchDisplayController.searchBar aboveSubview:self.tableView];
}
}
I encountered the same issue, and noticed that searchDisplayControllerDidEndSearch was being called twice. The first time, the superview of self.searchDisplayController.searchBar is the UITableView, and the second time it's still a UIView.
With the accepted answer, I worry about unintended consequences or unneeded overhead from re-inserting the subview every time the search bar is double-tapped, and I also worry about it breaking with future iOS versions. Fortunately, we can take advantage of the superview strangeness like this:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
if (self.tableView != self.searchDisplayController.searchBar.superview) {
[self.tableView insertSubview:self.searchDisplayController.searchBar aboveSubview:self.tableView];
}
}
If I had to guess what was happening, the UISearchBar is automatically creating a temporary UIView as its superview when it's active – this is the view seen when the search is being performed. While the UISearchBar is being dismissed, the superview gets set back to be the UITableView it had before, unless it gets dismissed so quickly that it was never properly initialized, in which case it cleans up improperly and the UITableView never gets the UISearchBar back as its child.
This solution still isn't ideal, and I think Apple must be doing something different in its own apps because their search bar UX feels a bit better. I think it would be better not to handle the second tap in the first place until the UISearchBar was ready. I tried using the other UISearchBarDelegate methods to do this, but I couldn't find an appropriate hook to override the current behavior.
I had the same problem with iOS 7 and I solved it from the apple documentation. The error most people do is that they associate the UISearchBar variable to the self.searchDisplayController.searchBar as the same...! NO NO..! They are 2 different things!!! UISearchBar should be declared and initialized and then wrapped into self.searchDisplayController as searchBar then later wrapped into self.tableView.tableHeaderView by so doing it will not disappear!!!
self.searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchDisplayController.delegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.searchResultsDelegate = self;
[self.searchBar setPlaceholder:#"search the hell in me"];
self.tableView.tableHeaderView = self.searchDisplayController.searchBar;
More refined approach for #lehrblogger solution:
- (void)addSearchDisplayControllerBackToTableView {
if ([self.searchDisplayController.searchBar isDescendantOfView:self.tableView] == NO) {
NSLog(#"Search bar is not in current table view, will add it back");
[self.tableView insertSubview:self.searchDisplayController.searchBar aboveSubview:self.tableView];
[self.searchDisplayController setActive:NO animated:YES];
}
}
Reason for this approach: While searching the search bar is moved to search container and the superview of search bar is always some other view other than current table view.
Note: This will dismiss the search, because user tapped more than once on search bar.
Code is:
OptionsTableViewController *optionsTableVc = [[OptionsTableViewController alloc] initWithItems:itemNames andSelectedItem:-1 andOrigin:-1];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:optionsTableVc];
optionsTableVc.delegate = self;
[self presentViewController:nav animated:YES completion:nil];
OptionsTableViewController is a custom viewcontroller which inherits from UITableViewController, a simple object
This code works well when on portrait, when rotating right once, or when rotating left once - but when I try to execute this code after the orientation changes to UpsideDown - it stops working - when I try to execute it, the current view gets "Flipped" (i.e from upside down to upside, or from landscape left to landscape right) and immediately disappears.
Your view controller that you are changing to probably is not returning yes to the following function for upsideDown
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
}
if your destination view controller does not already have this function in it you'll want to add it and return yes for all the orientations you want to support (sounds like probably all). If you do want to support all orientations you can just return yes from this function and that should probably fix your problem.
Adding this line fixed the odd behavior:
nav.modalPresentationStyle = UIModalPresentationPageSheet;
I've used this code to force an orientation change back to portrait when the user is finished watching the video (it allows viewing in landscape mode), before popping the video view controller off the navigation controller:
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
This worked perfectly until iOS 5.1.1. I've even tried to use the new present/dismiss methods after reading in another post that those should be used now:
[self presentViewController:mVC animated:NO completion:NULL];
[self dismissViewControllerAnimated:NO completion:NULL];
The problem is it doesn't work at all. After I rotated the video viewer to landscape and then pop it, my settings view (table view controller) comes back, but also in landscape mode.
I've even tried the tip from Here
"The setStatusBarOrientation:animated: method is not deprecated outright. However it now works only if the supportedInterfaceOrientations method of the topmost full screen view controller returns 0. This puts the responsibility of ensuring that the status bar orientation is consistent into the hands of the caller."
So I've experimented with setting a flag to force supportedInterfaceOrientations to return 0 (before calling the first code block above) but it doesn't work either.
Does anybody have a solution for this?
Thanks for your time and effort.
setStatusBarOrientation method has changed behaviour a bit. According to Apple documentation:
The setStatusBarOrientation:animated: method is not deprecated
outright. It now works only if the supportedInterfaceOrientations
method of the top-most full-screen view controller returns 0
Your root view controller should answer false to the method shouldAutorotate in order that your app responds to setStatusBarOrientation:animated
From Apple Documentation: "if your application has rotatable window content, however, you should not arbitrarily set status-bar orientation using this method"
To understand that, put a breakpoint in the shouldAutorotate method and you will see that it is called juste after setting the status bar orientation.
Here is how I fixed.
https://stackoverflow.com/a/14530123/1901733
The current question is linked with the question from the url above.
The statusBarOrientation is a real problem in ios6.
In an alert view method I implemented the following (pretty standard) piece of code for popping a modal view:
else if (buttonIndex == 1) {
EmergencyPlanViewController *emergencyPlanView = [[[EmergencyPlanViewController alloc] init] autorelease];
[emergencyPlanView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:emergencyPlanView animated:YES];
}
Somehow it gives me a black screen as result. I can't find what is wrong here.
I created the window in my MainStoryBoard and customized the class of the viewcontroller in IB to EmergencyPlanViewController.
The viewDidLoad method of the emergencyPlanView is triggered but it looks like the view is not loaded. Anyone an idea what's wrong here?
EDIT:
To be clear, I am not using seperate xib-files in my project. I only use the storyboard
In the xib file, is your UIView set to the File Owner's view. That is probably the problem. Also if you just apply init, that will load the EmergencyPlanViewControllerinterface builder file with the same name:
EmergencyPlanViewController.xib
So make sure in that case that either:
The EmergencyPlanViewController nib is indeed: EmergencyPlanViewController.xib
or that you write instead of init: initWithNibName://whatever nib name here
I managed to fix the black screen issue when presenting a modal view controller by setting a background color to the view in Interface Builder. I noticed that by default the background color of the view is set to something like black/white (see picture attached), although it appears in white. I don't know exactly what does this mean or how it is responsible for showing a black screen, but setting a single color or texture fixed it. PS: I've faced this when migrating from iOS SDK 5 to 6.
ios6
Try this:-
EmergencyPlanViewController *emergencyPlanView=[[EmergencyPlanViewController alloc] initWithNibName:#"EmergencyPlanViewController" bundle:nil];
emergencyPlanView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.navigationController presentModalViewController:emergencyPlanView animated:YES];
My question starts from a problem :
I started a project in Xcode : a Navigation Bar based one (with a TableView).
Then I added a few views, through IB or programmatically... which works perfectly fine.
Then, I decided to write my Own ViewClass, inherited from UIView, called OpenGlView (based on the view provided by Basic OpenGlES project in XCode), and its OpenGlViewController (inherited from UIViewController).
This works fine until I try to push the view Controller into my navBar: then I receive a "EXC__ BAD __ACCESS". I can't understand why it is ok whith any view but the one used for display OpenGL content...
And I actually have no idea how I can manage to develop a NavBar based App including a View displaying OpenGL contents... any idea?
(I also tried to add the OpenGlView as a subView of a basic UIView previously added to the NavigationBar, but I received the same error).
In the RootController :
OpenGlViewController *glvController;
if (glvController == nil)
{
glvController = [[OpenGlViewController alloc] initWithNibName:#"Gl View" bundle:nil];
glvController.title = #"GL View";
}
[self.navigationController pushViewController:glvController animated:YES];
in the OpenGlViewController :
- (void)loadView {
OpenGlView * view;
view = [[OpenGlView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = view;
[view release];
}
If it's localized to your OpenGL view, the crash may be the result of not properly initializing OpenGL items inside your view. See here for my recommendations on a potentially similar problem.