I know this is a very popular issue, but i´m having a hard time...so if anyone could help, it would most appreciate:
Im my master tableview (that i have made in storyboard) i have a plus button and every time the user presses that button, a picker view appears...depending on the selection in the picker view, a modal view appears (for this modal view, i have dragged a simple view controller in storyboard and gave it a storyboard id). Each modal view has textfields, and i want to dismiss the keyboard every time the user enters something...to create the modal view i have done this:
CobTableview *produtoCob =[self.storyboard instantiateViewControllerWithIdentifier:#"cobId"];
produtoCob.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:produtoCob animated:YES completion:nil];
produtoCob.view.superview.frame = CGRectMake(0, 0, 350, 512); //do this after presentModalViewController
produtoCob.view.superview.center = self.view.center;
produtoCob.managedObjectContext = self.contextProd;
How can i resolve this?
To everyone that has the same issue...i found out that you need both methods in your modal view controller class :
- (BOOL)disablesAutomaticKeyboardDismissal
return NO
-(BOOL)textFieldShouldReturn:(UITextField *)textField
([textField resignFirstResponder];
return yes
Related
I have two View Controllers. First one have sendbutton that segue to second view controller. Action Segue is Show. Each time click the button, new window pops up again. I don't want create new window again, and I just want to only one second View Controller.
And my FirstViewController.m :
- (void)prepareForSegue:(NSStoryboardSegue*)segue sender:(id)sender{
SecondViewController *destinationScene = [segue destinationController];
destinationScene.receivedString = _nextOne.stringValue;
}
SecondViewController.m :
- (void)viewWillAppear{
if(_myMutableArray == nil) _myMutableArray = [NSMutableArray array];
[_myMutableArray addObject:_receivedString];
}
What I want to is send a string in the first View Controller's TextField repeatedly to next View Controller. And keep using only one second window that created at first time.
See my Storyboard
You can do this in IB without any code. Update the Presentation attribute for the view controller in the destination view from Multiple to Single:
https://stackoverflow.com/a/36104388/287963
Don't set up the segue to happen automatically. Create an IBAction for the button, test whether your second view controller is already on the screen, and either segue or not depending on whether it already exists.
Is there a way to change the "parent" of a view controller so you can specify which view controller the back button will segue to without creating a custom back button?
Or is the only way to create a custom back button with a custom action?
If you have access to the navigation controller, you could manually insert a view controller in to its stack of view controllers [self.navigationController setViewControllers:] before the current view controller. That would allow the navigation controller to perform its regular actions yet still navigate back to your desired view controller.
Try To create a custom button like
UIBarButtonItem * buttonBack = [[UIBarButtonItem alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Back" ofType:#"png"]] style:UIBarButtonItemStylePlain target:self action:#selector(onBackClick:)];
[self.navigationItem setLeftBarButtonItems:#[buttonBack] animated:YES];
and make a method..
- (IBAction)onBackClick:(id)sender
{
// your code
// Write your code what you want to do...
}
In my app I have a list of items in a table view. Tapping on one of them, the app shows details of the item. Details appear and by back button of navigation controller, the app returns to list.
In the detail view I have implemented a method to swipe gesture in order to change the view to the details of the second element of the list and so on. It works.
The method that changes view is:
- (void)oneFingerSwipeLeft:(UITapGestureRecognizer *)recognizer {
int idx=currentIdx;
if (idx ==[todasLasTapas count]-1) { //last object vuelvo al primero
idx= -1;
}
ClassInfo *info =[allInfo objectAtIndex:idx+1];
//VIEW CONTROLLER
MoreInfo *moreInfoController =[[MoreInfo alloc]initWithNibName:#"MoreInfoController" bundle:nil];
//passing the details to view
moreInfoController.id = info.uniqueId;
moreInfoController.name = info.name;
// CHANGE TO NEXT VIEW
moreInfoController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:moreInfoController animated:YES];
}
The problem is that navigation controller disappears when the "second" view appears. My idea is that navigation remains in order to come back to the main table list.
Could someone help me please?
Unfortunately presenting modal view controllers happens outside of the UINavigationController stack. As a result, when you call presentModalViewController, you are bringing a controller onto the screen totally outside of stack of controllers managed by the UINavigationController.
You can preserve most of your implementation, but just switch out the presentation of the modal view controller, by simply adding MoreInfo's view as a subview to the current view.
If you'd like to preserve memory a little more gracefully, just switch between two UIView's (the currently showing view, and the next one to show - which is reused from the last detail view).
Here's an updated version of your code that could do this:
- (void)oneFingerSwipeLeft:(UITapGestureRecognizer *)recognizer {
int idx=currentIdx;
if (idx ==[todasLasTapas count]-1) { //last object vuelvo al primero
idx= -1;
}
ClassInfo *info =[allInfo objectAtIndex:idx+1];
//VIEW CONTROLLER
MoreInfo *moreInfoController =[[MoreInfo alloc]initWithNibName:#"MoreInfoController" bundle:nil];
//passing the details to view
moreInfoController.id = info.uniqueId;
moreInfoController.name = info.name;
[UIView transitionFromView:self.view
toView:moreInfoController.view
duration:2
options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished) {
[self.view removeFromSuperview];
}];
}
Here's a post that shows how to implement a custom animation to dissolve to another UIView:
How to make dissolve animation on changing views on iphone?
I load a view controller in my code using a segue in UIStoryboard. Based on a few user selected options, I then hide or show a UI control using an animation. It all works fine.
- (void)showComments {
NSLog(#"Show Comments");
_commentsTextView.hidden = NO;
_commentsTextView.frame = CGRectMake(435, 266, 475, 134);
[UIView animateWithDuration:1 animations:^{
_commentsTextView.alpha = 1;
_signatureButton.frame = CGRectMake(435, 420, 475, 134);
_cancelButton.frame = CGRectMake(568, 581, 100, 44);
_finishedButton.frame = CGRectMake(676, 581, 100, 44);
}];
}
Then I am presenting a view controller created in UIStoryboard using the following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
SigningViewController *signingVC = (SigningViewController *)[storyboard instantiateViewControllerWithIdentifier:#"SigningViewController"];
signingVC.object = self;
signingVC.signatureProperty = #"employeeSignature";
signingVC.startDate = self.startDate;
signingVC.endDate = self.endDate;
[self presentViewController:signingVC animated:YES completion:nil];
When this code fires all happens as expected except for one thing: All the custom animations that hid or showed a UI control revert back. It is as if by calling the presentViewController method, it is redrawing my existing view from the UIStoryboard.
Is there a way to get it to quit redrawing/reload my existing view from the Storyboard before displaying the new view modally?
I had the same problem too. Whatever I tried to make an animation change whenever a modal closed it seemed to reset back to the original storyboard.
The solution I had to go with was to add any animation view as an outlet to the header file. Take off the view out of the self.view or main view of the view controller on the storyboard and programmatically add it as a subview. Set the frame to where you want it and all the animation positions should be the same after you end the modal. It worked for me if you need more explanation and let me know.
I had just the same problem and posted it here in a more detailed form, A user named kokx helped me a lot and the answer is documented in my question page.
I have a PopoverController view that allows a user to download a file. On button press, the popOver view will expand in size, display download status, and the main view controller will be obscured by an unhidden "cover" view that has been added to the PopoverController's "passThroughViews" property so that the user can not accidentally dismiss the pop over while the file is downloading.
My problem is that, in storyboards, my main viewController is embedded in a Navigation Controller. I can't seem to cover the navigation controller's bar with a view in the storyboard, and if the user presses anywhere on the navigation bar then the popover will disappear and the user will lose the download's progress bar.
How do I either cover up the navigation bar with my "cover" view, or how do I add the navigation bar's view to my popOverController's passThroughViews?
Opening the Popover from the main viewController:
- (IBAction)openDataOptionsPopOver:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
PopOverViewController *optionsWindow = [storyboard instantiateViewControllerWithIdentifier:#"dataOptions"];
self.popUp = [[UIPopoverController alloc] initWithContentViewController:optionsWindow];
[self.popUp setDelegate:self];
[nextNavButton setEnabled:NO]; //Disabling barButtonItem on the navigationController
optionsWindow.containerPopOver = self.popUp; //Pointer to the popover, to resize it later.
optionsWindow.coverView = self.coverView; //Pointer to the coverView, to (un)hide later
[popUp presentPopoverFromRect:[sender frame] inView:[sender superview] permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Setting the passThroughViews property inside of the PopoverViewController:
//Expands the popOver on press of "refreshFileButton" to display progressView
-(void) explodeWindow
{
//setting self.navigationController.view and ...visibleViewController.view here didn't seem to work ...
[containerPopOver setPassthroughViews:[NSArray arrayWithObjects:coverView, nil]];
[containerPopOver setPopoverContentSize:CGSizeMake(600, 400) animated:YES];
[titleBarItem setTitle:#"Downloading File. Please Wait ..."];
[refreshFileButton setHidden:YES];
[progressView setHidden:NO];
[downloadLabel setHidden:NO];
[coverView setHidden:NO];
[progressView setProgress:0.0 animated:NO];
}
I've tried adding self.navigationController.view to passThroughViews with no success--it actually turns out to be a null pointer. And I can't seem to place a UIView at any level in storyboards that will cover all my controls without obscuring the popOver. What am I missing here? And thanks for reading.
Edit:
As Aglaia points out below out, implementing the following, and avoiding passThroughViews, is probably the best way to do this.
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
//Don't dismiss our popover when the view covering our controls is present
if([coverView isHidden]){
return YES;
}else{
return NO;
}
}
Maybe there is something I am missing, but why don′t you just implement a new view controller with its navigation bar set to none and present it modally on button press? Then when the download is finished you just dismiss the view controller.
If you want the user to see the underlying view you can use a UIAlertView instead.
Alternatively set you view controller as the delegate of the popover controller and forbid the user to dismiss your popover on touch outside through
- (BOOL) popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
Then when you want to dismiss it call dismissPopoverAnimated:
to cover the whole screen including navigation bar:
[myView setFrame:[[UIScreen mainScreen] bounds];
[self.navigationController.view addSubview:myView];