CALayer not changing position in UIScrollview - ios

I have a tableViewController with a dynamic UIView inside it, where it's layer position changes so that it stays underneath the status bar. I did the same to a regular View controller with a UIScrollView.
Where the "status banner" in the tableViewController does what it is suppose to, the status banner in the viewController does not.
The status bar's position is modified in a viewDidScroll method within each view controllers.
Why isn't the banner in the second view controller not moving?
Here is the code, it is the same in both view controllers:
-(void)scrollViewDidScroll: (UIScrollView*)scrollView
{
CALayer *layer = _statusBanner.layer;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset > 10)
{
[[self navigationController] setNavigationBarHidden:YES animated:YES ];
[_statusBanner setHidden:NO];
layer.position = CGPointMake(layer.position.x, scrollOffset + 10);
}
else {
[[self navigationController] setNavigationBarHidden:NO animated:YES ];
[_statusBanner setHidden:YES];
}
}

I figured a workaround with this issue. I had decided to leave statusBanner out of the scrollView of the viewController. The banner and the scrollview are both wrapped in the primary UIView of the viewController and the banner is placed just above scrollView.
I was looking too hard at the problem to see the easiest solution.

Related

Container/Child UIViewControllers and status bar

I'm trying to get a parent view controller to display a child view controller's view. I've got the following in the parent's viewDidLoad :
-(void)viewDidLoad
{
[super viewDidLoad];
// create child view controller
[self setMenuController:[[MenuViewController alloc] initWithNibName:#"MenuView" bundle:nil]];
[self addChildViewController:[self menuController]];
// move the child view down 30 pt
CGRect frame = [[[self menuController] view] frame];
frame.origin.y = 30;
[[[self menuController] view] setFrame:frame];
[[self menuController] setWantsFullScreenLayout:YES];
[[self view] addSubview:[[self menuController] view]];
[[[self menuController] view] setNeedsLayout];
}
The child view controller's xib is simply a red view with a centered, partially transparent UIImageView (to see overlap).
If I disable the status bar in application:didFinishLaunchingWithOptions:, I get the following:
If I enable the status bar, I get:
With a status bar, the child controller's UIView is automatically adjusted to make room for where the status bar would be (since the image view is centered, that's 10 pts on top and bottom). Since this is a child view, it should always use the full size of the view controller's view regardless of whether the parent will have a status bar. Is there any way to achieve this besides resizing any child views to be 20 pixels bigger, or using a wrapper view in the child view controller?
Try setting frame to menuController's view's bounds instead of its frame. Also, I'm not sure that you want setWantsFullScreen which should cause the view to underlap the status bar.
After Edit:
Try it like this, and see if this works.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self setMenuController:[[MenuViewController alloc] initWithNibName:#"MenuView" bundle:nil]];
[self addChildViewController:menuController];
[menuController didMoveToParentViewController:self];
menuController.view.frame = CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y +30, menuController.view.frame.size.width, menuController.view.frame.size.height);
[self.view addSubview:menuController.view];
}

UIScrollView does not scroll anymore after the view re-appear

I have a scrollview on the main view after the display of another view the scroll stop scrolling.
On view appear I tried to refresh the scroll but no luck
calling this:
-(void)refreshScrollView{
NSLog(#"scroll Content Height %f",answerScolledHeight );
NSLog(#"scroll View Height %f", scrollView1.frame.size.height );
[scrollView1 setScrollEnabled:YES];
[scrollView1 setContentSize:CGSizeMake(320, answerScolledHeight)];
[scrollView1 setContentOffset:CGPointMake(0, 0)];
}
It reads the right values without working:
2013-03-21 17:56:01.434 ----[38464:14003] scroll Content Height 256.000000
2013-03-21 17:56:01.434 ----[38464:14003] scroll View Height 194.000000
The problem comes after the display of the settings view:
SettingsController* controller1 = (SettingsController *)[self getSettingsViewController];
[self presentModalViewController:controller1 animated:YES];
And when the settings is closed the scroll does not work anymore
- (IBAction)doClose:(UIBarButtonItem *)sender {
[self dismissModalViewControllerAnimated:YES];
}
The viewDidAppear, I try to run some commands the first time to limitate the problems as I am using ECslidingViewController (a wipe menu)
- (void)viewDidAppear:(BOOL)animated{
if (!isActive){
answerUpY = self.answerView.frame.origin.y;
answerDownY = self.questionBackground.frame.origin.y +self.questionBackground.frame.size.height - self.answerToggle.frame.size.height - PADDING_1;
isActive = TRUE;
[self slidingControllerAppear];
}else{
[self refreshScrollView];
}
}

SplitViewController's master side sometimes is not rendered correctly when changing orientation in IOS 6.1

I have a tab bar controller that has some tabitems. Some of the tabitems are splitviewcontrollers. Sometimes, when I change orientation, the left side of the splitview controller does not render correctly, I have a black square in the bottom. By changing the orienation again, the problem is solved.
There is nothing special in my code. In the viewdidload I have:
[self.navigationController setNavigationBarHidden:YES];
self.splitViewController.delegate = self;
And one splitviewcontroller delegate method is handled trivially:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
I have nothing more, just some tableview on it with some cells on the detail side.
I've seen such issue and the only workaround I came up with was to reset the size of the left side view controller's view and also it's navigation controller's view:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (self.splitViewController) {
viewHeight = ...
navViewHeight = ...
CGRect viewFrame = CGRectMake(0, 0, 320, viewHeight);
self.view.frame = viewFrame;
CGRect navControllerViewFrame = CGRectMake(0, 0, 320, navViewHeight);
self.navigationController.view.frame = navControllerViewFrame;
}
}
Where viewHeight and navViewHeight you can calculate from screen height depending on current orientation (which has already been set when didRotateFromInterfaceOrientation: is called). I guess these values should be equal for you as you hide the navigation bar.

UINavigationBar hiding animation interferes with UIScrollView contentOffset animation

In an iPhone layout, I am hiding the UINavigationBar and at the same time I want the content of the UIScrollView beneath it to stay in the same place (scroll negatively while animating the nav bar height to zero):
[UIView animateWithDuration:0.3 animations:^{
CGFloat navBarHeight = CGRectGetHeight(weakSelf.navigationController.navigationBar.frame);
[[weakSelf navigationController] setNavigationBarHidden:YES animated:NO];
weakSelf.scrollView.bounds = CGRectOffset(weakSelf.scrollView.bounds, 0, -navBarHeight);
}];
The end result of the animation is ok - but during the animation, the scroll view jumps to its new position (- navbar height) and remains there until the end.
Do these two property animations interfere with each other?

Default iOS UINavigationBar animation isn't smooth

I'm working on an application and need to hide the UINavigationBar (and toolbar) to provide a fullscreen mode in the in-app browser.
When the app run this code the animation work just fine.
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.navigationController setToolbarHidden:YES animated:YES];
When I want to exit from the full-screen mode the animation isn't smooth at all.
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.navigationController setToolbarHidden:NO animated:YES];
During the animation a black rectangle is visible under the navigation bar, I think it is the UIWebView that resize itself (the toolbar animation work just fine.)
Any idea on how I can solve this problem?
Instead of using setNavigationBarHidden:animated: for hiding the navigation bar, try this:
In your view controller's viewDidLoad compute different frames for your navigation bar and your view:
// The normal navigation bar frame, i.e. fully visible
normalNavBarFrame = self.navigationController.navigationBar.frame;
// The frame of the hidden navigation bar (moved up by its height)
hiddenNavBarFrame = normalNavBarFrame;
hiddenNavBarFrame.origin.y -= CGRectGetHeight(normalNavBarFrame);
// The frame of your view as specified in the nib file
normalViewFrame = self.view.frame;
// The frame of your view moved up by the height of the navigation bar
// and increased in height by the same amount
fullViewFrame = normalViewFrame;
fullViewFrame.origin.y -= CGRectGetHeight(normalNavBarFrame);
fullViewFrame.size.height += CGRectGetHeight(normalNavBarFrame);
When you want to go fullscreen:
[UIView animateWithDuration:0.3
animations:^{
self.navigationController.navigationBar.frame = hiddenNavBarFrame;
self.view.frame = fullViewFrame;
} completion:^(BOOL finished) {
}];
When you want to return to normal:
[UIView animateWithDuration:0.3
animations:^{
self.navigationController.navigationBar.frame = normalNavBarFrame;
self.view.frame = normalViewFrame;
} completion:^(BOOL finished) {
}];
Tested this in the iOS 5.1 emulator. Hope you can use that. The "black rectangle" must be the default background color of your window, i.e. a gap between your navigation bar and your view.

Resources