I've made sure my navigation bar is not translucent and I've added this to my viewDidLoad so my navigation bar with prompt does not overlap my view when it first appears:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
This works great until I navigate to a view controller with a navigation bar that has no prompt, then pop back. When the navigation bar with prompt is redisplayed, the navigation bar extends downward to its full size (after viewDidAppear is invoked!) using some internal animation and my view is partially overlapped by the 30 pixel difference. Any ideas on what I can do about that?
I hate solutions like this. But my work-around is for iOS7 only, compare the view's frame.origin.y to the navigation bar's frame.origin.y + frame.size.height, in viewDidAppear. If they're different, I resize and reposition the view, animating so it doesn't look stupid. The view also has a scroll view as a subview, so I have to tweak that a bit too:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
CGRect nbFrame = self.navigationController.navigationBar.frame;
__block CGRect vFrame = self.view.frame;
__block CGFloat diff = nbFrame.size.height + nbFrame.origin.y - vFrame.origin.y;
if (diff > 0.0) {
__block CGSize size = scrollView.contentSize;
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
vFrame.origin.y += diff;
vFrame.size.height -= diff;
self.view.frame = vFrame;
size.height -= diff;
scrollView.contentSize = size;
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
}
}
If you have not used the autolayout.Try to set delta for that.
Related
I have a custom uiview that i am trying to update the frame size. I do it like this in a method once it is clicked. The method is called, and the frame value changes, however on the screen nothing happens!
if (!touched) {
GameBox *box = (GameBox *)[self.view viewWithTag:40];
[box setFrame:CGRectMake(20, 20, 100, 73)];
NSLog(#"%f", box.frame.origin.x);
markButton.enabled = NO;
guessButton.enabled = NO;
[self.view reloadInputViews];
NSLog(#"The action bar should now be hidden");
}
else if (touched) {
guessButton.enabled = YES;
markButton.enabled = YES;
[self.view reloadInputViews];
NSLog(#"The action bar should now be visible");
}
I guess you have hooked self.view to UIView in Interface Builder.
In order to change UIView frame, in Interface Builder go to File Inspector, and uncheck Use Autolayout, then in the code change the frame.
Hope this helps.
You need to set adjust the frame in the viewDidAppear (not viewDidLoad).
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = self.tableView.frame;
frame.origin.y += 100.0;
frame.size.height -= 100.0;
self.tableView.frame = frame;
}
Apparently this has something to do with table views within navigation controllers.
It is because of Auto Layout, however you could do it after Auto Layout done its work or change constraints of it. If you want to do it after auto layout add following.
- (void)viewDidAppear:(BOOL)animated {
dispatch_async(dispatch_get_main_queue(), ^{
box.frame = CGRectMake(20, 20, 100, 73)];
});
[self.view reloadInputViews] is generally used for FirstResponders. I Don't have much of an idea about your customview, but I think for just settings the frame you can use:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewFrame.frame=frame;//Frame Defined by you
[UIView commitAnimations];
can give better solution if i get a look at your custom view.
I have a search bar at the bottom of a view. The issue is whenever I type something in the keyboard, the search bar still remains at the bottom and I cannot view what I am typing. I would like to dynamically move it up whenever the keyboards pops up and then take back its original position after the keyboard disappears. And unfortunately the search bar has to be in the bottom for my app and kind of stuck in this.
Is there any way around to move the search bar up only when the keyboard appears? Any code snippets would be really helpful.
Your best bet is probably to use the –searchBarShouldBeginEditing: in the UISearchBarDelegate protocol.
It would look something like this :
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
CGRect newFrame = //some rect
mySearchBar.frame = newFrame;
return YES;//this is important!
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
CGRect originalFrame = //the original frame
mySearchBar.frame = originalFrame;
return YES;
}
EDIT: One of the other answers suggests using the UIKeyboard notifications, but that can be confusing. It does, however, give the advantage of working for every time the keyboard appears, rather than just when the UISearchBar is the first responder.
EDIT 2:
Mayur Joshi suggests using animation, which can be done like so:
[UIView animateWithDuration:duration
animations:^{
//what you want to animate (in this case, the search bar's frame)
}
completion:^(BOOL finished){
//what to do when the animation finishes
}];
EDIT 3:
If you don't want to obscure the view behind the search bar, you will have to shrink its height whenever the search bar moves up. It can go in the same place as the code to animate your search bar.
Hi, try this
sBar is UISearchBar object.
- (void)keyboardWillShow:(NSNotification *)aNotification
{
// the keyboard is showing so resize the table's height
CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = sBar.frame;
NSLog(#"%f",frame.size.height);
NSLog(#"%f",frame.origin.y);
frame.origin.y=frame.origin.y- keyboardRect.size.height;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
sBar.frame = frame;
NSLog(#"%f",frame.size.height);
NSLog(#"%f",frame.origin.y);
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
// the keyboard is hiding reset the table's height
CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = sBar.frame;
NSLog(#"%f",frame.size.height);
NSLog(#"%f",frame.origin.y);
frame.origin.y=frame.origin.y+ keyboardRect.size.height;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
sBar.frame = frame;
NSLog(#"%f",frame.size.height);
NSLog(#"%f",frame.origin.y);
[UIView commitAnimations];
}
You will have to use a UIScrollView and keep this search bar in that scroll View. Now, when you start editing the Search Bar, that is,
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar
set the scrollRectToVisible method for the UIScrollView so as to make your SearchBar visible like this....
[yourScrollView scrollRectToVisible:CGRectMake(0, 300, yourScrollView.frame.size.width, yourScrollView.frame.size.height) animated:YES];
And when you have written the text in the search bar, i.e
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar1
set the Scroll view scrollRectToVisible to its original size.
[yourScrollView scrollRectToVisible:CGRectMake(0, 0, yourScrollView.frame.size.width, yourScrollView.frame.size.height) animated:YES];
I got the code from this question: How to hide UITabBarController programmatically? which is brilliant, however the view doesn't expand to fit the space left by the tab bar now.
I have set the appropriate UIViewAutoresizingMasks to the view, but I'm assuming that just because its hidden doesn't mean its not still taking up the space?
Anyway, if I do [self.navigationController setNavigationBarHidden:YES animated:YES]; then the navigation bar moves up and off the screen expanding the view with it.
How can I replicate this behavior for the Tab Bar?
Turns out its not quite possible. Best way is to present a modal view (navigation) controller instead of pushing a view controller.
This worked great for me! (combines solutions from other posts mentioned -580 is randomly large number)
for(UIView *view in self.tabBarController.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 580, view.frame.size.width,
view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y,
view.frame.size.width, view.frame.size.height +40)];
}
}
-(void)hideTabBar
{ UITabBarController * tabbarcontroller= appDelegate.tabBarVC;
if (tabbarcontroller.tabBar.isHidden)
{
return;
}
tabbarcontroller.tabBar.hidden=YES;
CGRect frm=tabbarcontroller.view.frame;
frm.size.height += tabbarcontroller.tabBar.frame.size.height;
tabbarcontroller.view.frame=frm;
}
-(void)showTabBar
{ UITabBarController * tabbarcontroller=appDelegate.tabBarVC;
if (!tabbarcontroller.tabBar.isHidden)
{
return;
}
CGRect frm=tabbarcontroller.view.frame;
frm.size.height -= tabbarcontroller.tabBar.frame.size.height;
tabbarcontroller.view.frame=frm;
tabbarcontroller.tabBar.hidden=NO;
}
here appDelegate is = (AppDelegate *) [[UIApplication sharedApplication] delegate]
tabBarVc is UITabBarController *tabBarVC defined as property in app delegate
in NSContraints era, do NOT try to modify frame by code, bad things may happen.
Use:
pushedViewController.hidesBottomBarWhenPushed = YES;
typically set hidesBottomBarWhenPushed to yes in prepareforSegue, ANYWAY before iOS actually pushes the new controller.
The easiest way is probably to set a new frame for the view:
CGRect viewFrame = view.frame;
viewFrame.size.height += 40; // Change this to the height of the tab bar
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
view.frame = viewFrame;
[UIView commitAnimations];
I got stuck in here,
I have a custom scrollview in a view this scroll view has an add field button which lets user to add new text field to the scrollview. When user taps on a particular textfield keyboard appears and hide the textfield, to overcome this I followed UICatalog example, but it moves the whole scrollview up
to prevent this I followed UICatalog example and did this
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if (sender.frame.origin.y>109) {
moveScrollViewUpBy=(sender.frame.origin.y-109+10);
[self viewMovedUp:YES];
}
}
-(void)viewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = formScrollView.frame;
if (movedUp)
{
if(rect.origin.y == 0.0f){
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
}
else
{
if(rect.origin.y != 0.0f){
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
}
self.formScrollView = rect;
[UIView commitAnimations];
}
here
#define kOFFSET_FOR_KEYBOARD 160.0
but this shifts the scroll view up,
I want that when i tap on a textfield down below in scroll view... scroll view scrolls and that textfield appears....
is it possible to do so....otherwise suggest me some other solution
I have one more query srollview just stop scrolling while the keyboard stays on screen. Is there any way to overcome this
You probably just want to set the scrollView's contentOffset property, rather than adjust its bounds.
Implement the UITextViewDelegate and do the following:
- (void)textViewDidBeginEditing:(UITextView *)textView {
keyboardShowing = YES; //helper ivar
[self sizeToOrientation];
[self.scrollView scrollRectToVisible:textView.frame animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
keyboardShowing = NO;
[self sizeToOrientation];
}
Helper method:
//fit to the appropriate view sizes
- (void)sizeToOrientation {
CGSize size;
if( keyboardShowing )
size = CGSizeMake(320, 190); //make room for keyboard
else
size = CGSizeMake(320, 420); //full height with tabbar on bottom
self.scrollView.frame = CGRectMake(0, 0, size.width, size.height);
}
This works well for me.
I'm trying to implement a UITextView in a table cell at the bottom of a table view.
I've tried the suggestions here Making a UITableView scroll when text field is selected, and other solutions as well, but they're a bit different because I have to artificially add extra height to the current view in order to create space for the keyboard.
Here's what I added to the previous solution in order to port it to my app.
-(void) keyboardWillShow:(NSNotification *)note {
CGRect frame = self.view.frame;
frame.size.height += keyboardHeight;
frame.origin.y -= keyboardHeight;
self.view.frame = frame;
}
-(void) keyboardWillHide:(NSNotification *)note
{
CGRect frame = self.view.frame;
frame.size.height -= keyboardHeight;
frame.origin.y += keyboardHeight;
}
Doing this will correctly add the height to the view and scroll to the cell, but after restoring the original view's height, scrolling beyond the current visible view becomes impossible, even though there is valid content outside of the boundaries (I see the text view before the scroll bar bounces back).
If I try to save the tableview's frame or bounds (not the view) in keyboardWillShow and restore them in keyboardWillHide, the scrolling will be restored, but the view will be cut in half.
Are there any remedies to this besides hard-coding the additional height to the bottom of the view?
I was able to solve my problem of the locked scrolling by removing the code that edits the view's origin. In addition, I implemented scrolling to the bottom cell by using the tableview's contentSize property in my calculations.
-(void) keyboardWillShow:(NSNotification *)note
{
if(!isKeyboardShowing)
{
isKeyboardShowing = YES;
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
CGFloat keyboardHeight = keyboardBounds.size.height;
CGRect frame = self.view.frame;
frame.size.height += keyboardHeight;
self.view.frame = frame;
CGPoint scrollPoint = frame.origin;
scrollPoint.y += _tableView.contentSize.height - keyboardHeight;
[_tableView setContentOffset:scrollPoint animated:YES];
}
}