UIScrollView contentOffset is set automatically when switched to foreground - ios

I am developing an iPhone application. I have my code implemented this way:
RootViewController has UIScrollView as its view. Then RootViewController pushes another UIViewController say vc which again has UIScrollView (sv) as its view.
The bounds/frame size of sv is (320, 460) and content size is (320, 520). So, sv is now scrollable vertically. Hence, I have set content offset of sv to be (0, 60).
I switch to background using Home button of iPhone and again put my application to Foreground. In this case my sv content offset is set to (0, 0) automatically with animation.
When I tried to override setContentOffset: I noticed that some library call [adjustsIfNeeded], sets content offset to be (0, 0).
Why is this happening?

This was because, my base view of UIViewController was UIScrollView. I changed it to a UIView and then added UIScrollView as its subview. Now, it works fine.

Related

UITableView Scroll Indicator in Left Side

I need to bring Scroll indicator to the left side of a table view.
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, self.tableView.bounds.size.width-8);
Above code is working fine for iPhone 5, 5C etc.
But scroll indicator is not positioned well in iPhone 6. It shows some padding from left side.
In viewDidLoad method, the bounds of the view are not set correctly and if view is set in nib/storyboard, bounds are set accroding to size of view set there.
I guess, in your nib.storyboard you have chosen iPhone 5S/iPhone 5S size to design the view and henceit works in those devices.
If you set tableView's scrollIndicatorInsets in viewDidLayoutSubviews method, the indicator inset should set correctly.

UIScrollView Bounces To Either Top Or Bottom

I have a UIScrollView for which I have a UIView which is the subview of the scroll view , the UIView has a lot of other subviews and I am getting the height for it dynamically after adding the subviews , this is my piece of code to add the view to scroll view
CGRect frameOfView = CGRectMake(0, 0,Get_Bounds.width, globalYPosition);
self.parentProductDetailView = [[UIView alloc]initWithFrame:frameOfView];
I am first initialising the view this way and then after adding all subviews I am doing this,
frameOfView.size.height = globalYPosition;
[self.parentProductDetailView layoutSubviews];
self.parentProductDetailView.frame = frameOfView;
[self.productDetailScrollView addSubview:self.parentProductDetailView];
self.productDetailScrollView.contentSize = CGSizeMake(0, self.parentProductDetailView.frame.size.height *1);
But my scrollview does not scroll properly it either sticks to top or bottom.
Here globalYPosition is the sum of height of all subviews added to parentProductDetailView
The procedure you used seems correct. No matter the subviews your scroll view should scroll properly by simply using a larger content size then its frame size.
The scroll view may stick, snap to some points if paging is enabled which is what is happening in your case. If the content view is larger then 1.5th of the frame size then the scroll view will snap to top/bottom or left/right. If it is smaller then it will only snap to starting position.
This may be very useful for situations like having a side menu that takes a part of a screen but in your case you should simply disable the paging and scrolling should work fine.

Start on specific place on UIScrollView

I would like to know if there is a way to center a UIScrollview, if you will. Let me explain: I've made a ScrollView and connected it to some view controllers so that I can slide back forth, similar to as you would in snapchat. I have 3 view controllers. I wanted to know if there was a way that I could start off in the center view controller (Viewcontroller 2 or the "middle" view controller) instead of always starting on the very left. Thank you for the help.
Set your scrollview's contentOffset.x value to a multiple of your viewController width (most likely the width of your screen).
scrollView.contentOffset = CGPointMake(yourViewControllerWidth, 0)
Where contentOffset.x = 0 is all the way to the left, setting it to the width of your viewcontroller will move the scrollview to the beginning of the next viewcontroller.

UIScrollView and PanGestureRecognizer

I’m have a view that contains a regular UIView and a UIScrollView. The UIView sits above the UIScrollView offscreen. The UIScrollView typically occupies the entire screen. (It should be noted that I’m not using Autolayout). When the user scrolls to the top of the scrollview content I would like the UIView to start appearing on the screen. And when it reaches a certain threshold have the UIView snap into place and occupy the screen.
My initial thought was to use the UIScrollView delegate method, and adjust the superview.frame.orgin.y value when the scrollview contentOffset.y value is negative.
func scrollViewDidScroll(scrollView: UIScrollView) {
pullDownInProgress = scrollView.contentOffset.y <= 0.0
if pullDownInProgress {
self.view. = (-self.view.height / 2) - scrollView.contentOffset.y
}
}
However, this creates a stretching between the UIView and the UIScrollView due the scrollview bounce setting. If I turn off the bounce setting then the scrollview.contentOffset is never less then zero, therefore my superview frame is never adjusted.
Any suggestions on how to accomplish this?
You don't need to change the superview.frame, instead move the offscreen view down by its height so that it can appears and any bouncing effect for the scroll view might be hidden by that view.Or you can even move both the scroll view and the offscreen view with the height of the offscreen view. It really depends whether your offscreen view is transparent or not

How to determine UINavigationBar size before device orientation changes

I'm writing an app in Objective-C using Xcode 6 and iOS 8. The app needs to be able to be deployed on an iPhone 5, 6, or 6+.
If you want to get straight to answering my question, jump down to the last sentence. If you want to understand why I have the question I do, or maybe how I can alter my UI layout in order to solve my problem another way, read on.
In one of my view controllers, I have a scroll view whose top is constrained to the bottom of the navigation bar, and whose bottom is constrained to the top of a table view. The table view's bottom is constrained to the bottom of the view controller's main view (i.e. to the bottom of the phone).
The scroll view contains subviews that expand/contract when the user taps on them. I want the scroll view to grow as its subviews grow, but obviously I don't want the scroll view to grow off screen because it looks bad and because it would cause unsatisfiable constraints (the table view's top--which is constrained to the bottom of the scroll view--would cross below its bottom--which is constrained to the bottom of the main view...this causes an error). So, I use the following code to make the scroll view resize itself according to its subviews sizes without growing right off the screen:
// The max height before the scroll view would go off screen, which would
// mess up the table view's constraints and cause all sorts of problems
CGFloat maxHeight = self.view.size.height
- self.navigationController.navigationBar.frame.size.height
- [UIApplication sharedApplication].statusBarFrame.size.height;
// The height of all the subviews in the scroll view.
CGFloat height = _scrollContentView.frame.size.height;
if (height > maxHeight) {
height = maxHeight;
}
self.scrollViewHeightConstraint.constant = height;
Now for the fun part. Originally, I called this code to re-evaluate and reset the size of the scroll view whenever I rotated the device from portrait to landscape, or vice versa. However, when I would rotate the phone from portrait to landscape, I was getting constraints errors. I determined that it was because I was calling this code after the rotation, when the main view's height was smaller, but the scroll view's height was still large (causing the table view's top to go below the bottom, etc. as I explained before). So, I just moved the code to be called before the rotation (I called the code in the viewWillTransitionWithSize:withTransitionCoordinator: method). This all makes sense so far.
However, now, the problem is that the navigation bar's height changes when the rotation occurs, but the viewWillTransitionWithSize:... method does not include any details on this change (it only gives the new size that the main view will be when rotation is completed, not the new size the navigation bar will be as well).
So, I need someway to determine the new size of the navigation bar before the device's orientation actually changes (just like I can determine the main view's new size before the device's orientation actually changes using the viewWillTransitionWithSize:... method).
Any ideas? TIA!
So, here's my work around in its simplest form:
/*
* This method gets called when the device is about to rotate.
*/
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Set the scroll view's height to 0 to avoid constraints errors as described
// in the question.
self.scrollViewHeightConstraint.constant = 0;
}
/*
* At the point when this method gets called, the device rotation has finished altering
* the frames of the views in this view controller, but the layout has not finished
* so nothing has changed on screen.
*/
- (void)viewWillLayoutSubviews
{
// The max height before the scroll view would go off screen, which would mess up
// the table view's constraints and cause all sorts of problems
CGFloat maxHeight = self.view.size.height
- self.navigationController.navigationBar.frame.size.height
- [UIApplication sharedApplication].statusBarFrame.size.height;
// The height of all the subviews in the scroll view.
CGFloat height = _scrollContentView.frame.size.height;
if (height > maxHeight) {
height = maxHeight;
}
// Reset the scroll view's height to the appropriate height.
self.scrollViewHeightConstraint.constant = height;
[super viewWillLayoutSubviews];
}

Resources