UIScrollView setContentSize doesn't work - ios

I have a really big problem with UIScrollView. To make sure it wasn't my actual project, I created a NEW project, iPhone only, for iOS 6 and 7. I disabled autolayout.
I created a Tab Bar project
I created a view controller,
embedded it in a navigation controller and connected it as Tab bar
item #0
I put a UIScrollView in my view.
I connected the scrollview in the custom UIViewController created for this view.
I synthesized my IBOutlet and set the delegate to self. I also
implemented delegate in .h
Here is my code (ViewDidLoad):
self.scrollView.delegate = self;
[self.scrollView setScrollEnabled:YES];
[self.scrollView setContentSize:CGSizeMake(self.view.frame.size.width, 20000)];
NSLog(#"contentSize width %f", self.scrollView.contentSize.width);
NSLog(#"contentSize height %f", self.scrollView.contentSize.height);
NSLog(#"%#", NSStringFromCGAffineTransform(self.scrollView.transform));
It returns me "contentSize width 20000.000000", "contentSize height 0.000000
" and "[1, 0, 0, 1, 0, 0]". It scrolls left-right where it should scroll up-down
Please help!

I had the same issue until I realized I hadn't set the UIScrollView delegate. Also, if you're using auto layout, you need to wait for the layout to be applied to the UIScrollView. This means you should set the Content Size in "viewDidLayoutSubviews".

In viewDidLoad method, frame may not be correct, move the code to this method:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Your code
}

Use this code. ScrollView setContentSize should be called async in main thread.
Swift:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
DispatchQueue.main.async {
var contentRect = CGRect.zero
for view in self.scrollView.subviews {
contentRect = contentRect.union(view.frame)
}
self.scrollView.contentSize = contentRect.size
}
}
Objective C:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
dispatch_async(dispatch_get_main_queue(), ^ {
CGRect contentRect = CGRectZero;
for(UIView *view in scrollView.subviews)
contentRect = CGRectUnion(contentRect,view.frame);
scrollView.contentSize = contentRect.size;
});
}

Okay, there is absolutely nothing wrong with your code. So some suggestions:
Make sure you added to your .h file like so:
#interface yourViewController : UIViewController <UIScrollViewDelegate> {
}
Try moving this snippet of code to the "viewWillLoad" method:
- (void)viewWillAppear:(BOOL)animated {
self.scrollView.delegate = self;
[self.scrollView setScrollEnabled:YES];
[self.scrollView setContentSize:CGSizeMake(self.view.frame.size.width, 20000)];
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var contentRect = CGRect.zero
for view: UIView in scrollView.subviews {
if !view.isHidden {
contentRect = contentRect.union(view.frame)
}
}
scrollView.contentSize = contentRect.size
scrollView.contentSize.width = self.view.frame.width
}
Working Swift 3.X code. Converted #Karen Hovhannisyan's answer.

Related

UIScrollView content size out of bounds in ios7

I have a wired bug in iOS7, my UIScrollView content height is out of screen bounds and I can't scroll down to the bottom.
I'm using AutoLayout.
The view heirarchy is:
- UIView
- UIScrollView
- UIView
- Buttons
In iOS8+ it's working fine.
I have this in viewDidLoad:
if ([self respondsToSelector:#selector(automaticallyAdjustsScrollViewInsets)]) {
self.automaticallyAdjustsScrollViewInsets = NO;
}
And this also:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.scrollView.contentSize = CGSizeMake(320, 1380);
}

UIScrollView Automatic ContentSize

I'm trying to set the ContentSize of my UIScrollView automatically, but when I do it, the frame height of uiscrollview is not with the screenHeight as I want.
There's my code:
-(void) viewWillAppear:(BOOL)animated {
[self.scrollGeral setTranslatesAutoresizingMaskIntoConstraints:YES];
[self.scrollGeral setContentSize:(CGSizeMake(screenSize.size.width, [self calcularAlturaScrollView]))];
}
-(CGFloat) calcularAlturaScrollView {
CGFloat scrollViewHeight = 0.0f;
for (UIView* view in self.scrollGeral.subviews)
{
scrollViewHeight += view.frame.size.height;
}
return scrollViewHeight;
}
Therefore, I'have tried to include the following line:
[self.scrollGeral setFrame:CGRectMake(0, 0, screenSize.size.width, screenSize.size.height)];
But if I do it, the UIScrollView 'disabled' the scroll
I solved my problem with the following code:
-(void) viewDidLayoutSubviews {
[self.scrollGeral setContentSize:(CGSizeMake(screenSize.size.width, [self calcularAlturaScrollView]))];
}

Move a UIView based on the content offset for UIScrollView

I am trying to pull down a UIView (Like a Pull Down Menu) when the user scrolls below a Y-offset of 0.0 in the UITable View. If the user pulls down below -80.0 Y-Offset, then the PullDownMenu locks itself , until the User scrolls the other way.
My implementation for just the UITableView's ScrollView is as follows : [lock:false initially]
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if(isChangingOffset)
return;
if(resetDrag)
{
[self setScrollViewOffset:scrollView offsetTo:CGPointMake(0, -80.0)];
resetDrag = false;
}
float xx = scrollView.contentOffset.y;
NSLog(#"Offset :%f",xx);
if(xx - begginOffset > 0.0 && lock && !doneDragging)
{
offsetChange = xx - begginOffset;
begginOffset = xx;
lock = false;
[self setScrollViewOffset:scrollView offsetTo:CGPointMake(0, -80.0)];
}
if(lock){
[self setScrollViewOffset:scrollView offsetTo:CGPointMake(0, -80.0)];
}
if(xx <=-80.0)
{
[self setScrollViewOffset:scrollView offsetTo:CGPointMake(0, -80.0)];
lock = true;
}
}
- (void)setScrollViewOffset:(UIScrollView *)scrollView offsetTo:(CGPoint)offset{
- (void)setScrollViewOffset:(UIScrollView *)scrollView offsetTo:(CGPoint)offset{
isChangingOffset = true;
scrollView.contentOffset = CGPointMake(0, -80.0);
isChangingOffset = false;
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
float x = scrollView.contentOffset.y;
begginOffset = x;
doneDragging = false;
if(lock){
resetDrag = true;
}
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
doneDragging = true;
}
Here is a working video of how it looks : Video
The blue color is a UIView that I have added as a subview in the UITableView.
My problem is , I am trying to pull down a UIView,lets call it menuView (that is not a subview of the tableView) based on the UITableView's contentOffset. I could have simply added the menuView in the UITableView like I added the blue color view. But that is only accessible via the table, that is when I scroll to the top and drag it down. But I want the menuView to be 'pull-able' like the notification center at any time.
On using the Y-contentOffset of scroll view, the menuview pull down animation is not smooth. And it stops midway or goes too low. It is jerky and not always the same. How can I implement this ?
Here the sample code for your UIScrollView :
ViewController.h
#interface ViewController: UIViewController {
UIScrollView *scrollView;
}
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
ViewController.m
#implementation ViewController
#synthesize scrollView;
- (void)viewDidLoad
{
[super viewDidLoad];
[self scrollView];
}
- (void)scrollText{
[scrollView setContentSize:CGSizeMake(320, 800)];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.clipsToBounds = YES;
}
And iside you can put wat you want, from code or interface builder.
For a PullDownMenu you can see this GitHub:
MBPullDownController
Hope this help you and simplify your code ;)

Cannot resize UITableView xcode 4.5.1 IOS 5.0

First off, believe me when I say I have tried all of the suggestions. But I am willing to try them again, so feel free to comment/answer. Currently my code looks like:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = CGRectMake(tblView.frame.origin.x, tblView.frame.origin.y, tblView.frame.size.width, tblView.contentSize.height);
[tblView setFrame:frame];
[tblView reloadData];
CGRect contentRect = CGRectZero;
for (UIView *view in scrollView.subviews)
contentRect = CGRectUnion(contentRect, view.frame);
[scrollView setContentSize:contentRect.size];
scrollView.frame = CGRectMake(scrollView.frame.origin.x, scrollView.frame.origin.y, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
}
My #interface is:
#interface VH_HotelsListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageView;
IBOutlet UITableView *tblView;
NSMutableArray *hotelArray;
}
I have tied my storyboard table view into the tblView above. My table view is populated at run time from my database, so I know there are no issues there.
As you can see from above, I am getting the content size of the table view and trying to adjust the frame to the same height. I am accurately getting the content size, though, because it resizes my scroll view to that height. It just does nothing to the table view, unfortunately. Though if I NSLog(#"Table View Height: %g", tblView.frame.size.height) just after setting it, I get the same number as for the content size Table View Height: 3166. So it's like it's working, but it's not actually expanding it.
Well, I got no answers, so I've updated my project. I've taken the UITableView out of my storyboard altogether and now just create it in code:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
tblView = [[UITableView alloc] initWithFrame:CGRectMake(0, 150, 320, 500) style:UITableViewStyleGrouped];
tblView.dataSource = self;
tblView.delegate = self;
[scrollView addSubview:tblView];
}
Then in viewDidAppear:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = CGRectMake(tblView.frame.origin.x, tblView.frame.origin.y, tblView.frame.size.width, tblView.contentSize.height);
tblView.frame = frame;
[tblView reloadData];
}
This seems to be working.

Scroll VIiew Class iOS

My program doesnt even go into the scrollViewDidScroll method. I have no idea why. My view did load looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the size of the content to be displayed
self.scrollView.contentSize = CGSizeMake(self.scrollView.bounds.size.width * ScrollViewControllerNumberOfPages, self.scrollView.bounds.size.height);
// Turn on paging in the scroll view (can also be done in Interface Builder)
self.scrollView.pagingEnabled = YES;
NSLog(#"CurrentPage ViewDidLoad%#",self.pageControl.currentPage);
switch (self.pageControl.currentPage)
{
case 1:
[self.minkyImageView setImage:[UIImage imageNamed:#"monkey_1.png"]];
NSLog(#"case1");
break;
case 2:
[self.minkyImageView setImage:[UIImage imageNamed:#"Shape1.png"]];
NSLog(#"case2");
break;
default:
break;
}
}
Also i have implemented the scrollviewDelegate on my interface like this. I don't see what i am doing wrong. It doesn't even go into the method called scrollViewDidScroll.
#interface MinkyScreenSwapViewController: UIViewController <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat contentWidth = scrollView.bounds.size.width;
CGFloat halfContentWidth = contentWidth / 2;
NSInteger currentPage = (scrollView.contentOffset.x + halfContentWidth) / contentWidth;
self.pageControl.currentPage = currentPage;
NSLog(#"CurrentPage");
}
Try out:
self.scrollView.delegate = self;
Hope this helps.
Try these codes
scrollView.delegate = self;
scrollView.userInteractionEnabled=YES;
If you are adding scroll view over image view, you have to explicitly set
imageView.userInteractionEnabled=YES;
For more convenience set
[[scrollView superView] setUserInteractionEnabled:YES];
These will make your scrollView delegate method active.

Resources