Unable to scroll in scroll view - ios

This is my view layout in storybaord:
My Scroll view frame is set to be 320x568, and in my view controller I have set
self.scrollView.scrollEnabled = YES;
[self.scrollView setContentSize:CGSizeMake(320,1000)];//obviously content is larger than frame
However, the scroll still doesn't work. So I enabled vertical bounce, and found that every time when I drag down it just bounces back to original position. Can anyone help me fix this issue?

First turn off AutoLayout - click on scrollview and uncheck Use AutoLayout
In your .h file add the UIScrollViewDelegate for example:
#interface myViewController : UIViewController <UIScrollViewDelegate>
In your .m file in viewDidLoad set
self.myScrollView.delegate = self;
self.myscrollView.scrollEnabled = YES;
self.myscrollView.contentSize=CGSizeMake(320.0, 1094.0);
keep Bounces ON and set scrollview frame 320 X 960

In your .h file add the UIScrollViewDelegate for example:
#interface myViewController : UIViewController <UIScrollViewDelegate>
In your .m file in viewDidLoad set
self.myScrollView.delegate = self;

If you have one subview in your scrollview, as you do, the scrollview will scroll to the dimensions of that view. See the answer here for details.

view.userInteractionEnabled = YES

Related

Layout not changing when parent (UIView) size is changed

I have a UIView and inside this UIView I have another UIView, lets say parent and child UIView. I have set height and width of parent UIView to 400 in storyboard and set child view constraint to take 8px margin from top, left right and bottom from its superview.
But When I change size of parent view to 200, size of child view remain same. I have tried this in both viewdidload and viewdidappear
CGRect frm = self.mainTimerView.frame;
frm.size.width = size;
frm.size.height = size;
self.mainTimerView.frame = frm;
when I change parent view to 200 child should set it self to 200-16 height and width according to constraints.
You should not mix using uiconstraint with using frame.If you want to change the size when using uiconstraint, you should make the outlet of the constraint, and then change the constraint's constant property.Call layoutIfNeeded,then you can get the right frame.
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *mainTimerView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainTimerViewHeightConstraint;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view layoutIfNeeded];
NSLog(#"%#",#(self.mainTimerView.frame.size.width));
self.mainTimerViewHeightConstraint.constant = 100;
[self.view layoutIfNeeded];
NSLog(#"%#",#(self.mainTimerView.frame.size.height));
}
#end
Calling layoutIfNeeded aim to to force the layout of subviews before drawing, then viewDidLayoutSubviews will be called. Note that you can get the correct frame in viewDidLayoutSubviews. In other words, you can get the right frame after viewDidLayoutSubviews has been called.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSLog(#"%#",NSStringFromCGRect(self.mainTimerView.frame));
}
1) Change the height constraint of the mainview.
2) Call the layoutIfNeeded method.
3) Do it on viewDidAppear.
Have you tried calling setNeedsLayout on the parent view? This call is used to ask a view to layout its subviews. From the setNeedsLayout's discussion section:
Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.
Calling layoutIfNeeded might be another option. But according to the docs, it forces an immediate layout, and therefore does not provide the consolidation benefit gained by using setNeedsLayout.
layoutIfNeeded documention:
Lays out the subviews immediately.
Plz create the IBOutlet of height Constraint of parent view.
IBOutlet NSLayoutConstraint *RedViewHeightconstraint;
- (void)viewWillAppear:(BOOL)animated
{
RedViewHeightconstraint.constant = 500;
}
it will work for you
You just need to create IBOutlets of constraints of height and width of mainTimerView. Once you do so add these lines of code :
constraintOuterViewHt.constant = 200
constraintOuterViewWidth.constant = 200
You don't need to do anything else.
Check screen shot here

Delegate when constraints updated

I am facing an issue while using storyboard auto layout with UIScrollView. I am updating a constraint of a UIScrollView, and after that setting the content size of scrollview. But UIScrollView constraint takes a bit of time to update and initially UIScrollView is not able to scroll because of more height than a view. I can not change the current implementation.
Is there any way, notification or any delegate method to check that the constraints are updated, so that I can do further changes?
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *scrollViewHieghtConstraint;
self.scrollViewHieghtConstraint.constant = 500;
[self.scrollView updateConstraints];
[self.scrollView setContentSize:CGSizeMake(0, 1000)];
You can use - (void)updateViewConstraints selector of UIViewController.
You can also use - (void)updateConstraints selector of UIView if you have extended said view.
You can't call -updateConstraints directly. You have to mark the view's constraints as dirty and iOS will call that method on the next update cycle.
On a UIViewController's implementation, add this when you need the constraint to change:
self.scrollViewHieghtConstraint.constant = 500;
[self.view setNeedsLayout];
I'm assuming that UIScrollView is a subview of the UIViewController's view. If it's not, then call -setNeedsLayout on the scrollview's parent view.
And if you need to know when the subviews are already on their right place, you have a callback for UIViewController, called -viewDidLayoutSubviews

UIScrollView in Interface Builder not working

I originally had a normal view with a bunch of stuff in it, and I want that view to be an UIScrollView, so I created a new ScrollView and dragged everything over. The view is not scrolling.
After looking around - I unchecked use autolayout, but that didn't work. I also realize that this could be solved by setting contentSize, but I have access to this view through a variable that is of type UIView, and not UIScrollView. In other words I would be doing -
self.someController.view.contentSize = //something
where self.someController.view is only an UIView and contentSize is not a property of UIView(or at least that's what I'm seeing- I get compiler warnings).
Why is this scroll view not scrolling?
EDIT -
So I stupidly forgot I can cast - I did that, but it's still not working -
UIScrollView* basicCardView = ((UIScrollView *)self.detailController.view);
basicCardView.contentSize = CGSizeMake(basicCardView.frame.size.width * 12,
basicCardView.frame.size.height);
You need to connect your scrollview to Iboutlet var in .m .
Create var in your interface:
IBOutlet UIScrollView *scrollview;
And connect to your scrollview in storyboard, then you can set contentsize.
[scrollview setContentSize:CGSizeMake(2000,200)];
Elto has it correct. To elaborate: In your view controller .m say it's called MyViewController:
#interface MyViewController ()
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#end
Go back to storyboard, select your view controller and select the connections tab (last one on the upper right). You should now see an outlet called scrollView. Drag a connection from that outlet to the scroll view that you added to the scene.
Now the content size code can be written. Just to get it working, use large constants in content size, like:
self.scrollView.contentSize = CGSizeMake(1000, 1000);
The size you're setting in the post (on the wrong view) looks like it's just the size of one of the subviews. You want the content size of the scroll view to be more like a multiple of the scrollView's size. You want the rectangle it can scroll within to at least encompass the frame (not the bounds) of every subview it contains.

UIScrollView doesn't scroll in the right direction

I got a weird bug. I have a UIViewController with a UIScrollView embedded inside the UIView. Inside the UIScrollview are few images, but I need more space, so I want to put some images under the current ones. I did all the usual stuff to create and initialize my ScrollView, but instead of scrolling in the UP/DOWN direction, it scrolls LEFT/RIGHT … What is going on?
I declared "UIScrollViewDelegate" in the .h
My property #property (weak, nonatomic) IBOutlet UIScrollView *scrollViewContent; is connected to my scrollview in IB
My ContentSize is declared as: self.scrollViewContent.contentSize= CGSizeMake(self.scrollViewContent.frame.size.width, 1000); and whether I declare it in ViewDidLoad or viewDidLayoutSubviews doesn't change anything.
I set self.scrollViewContent.delegate = self;
in ViewDidLoad
UPDATE
Interestingly enough, I tried setting the ContentSize and then printing it to the console. As it turns out, the "Height" attribute always returns 0. Also, note that I set the "Width" to 1500, but it prints 2000. I'm not using auto-layout.
[self.scrollViewContent setContentSize:CGSizeMake(1500, 2000)];
NSLog(#"contentSize width %f", self.scrollViewContent.contentSize.width);
NSLog(#"contentSize height %f", self.scrollViewContent.contentSize.height);
Result:
"contentSize width 2000.000000"
"contentSize height 0.000000"
UPDATE 2 If I take the exact same Code and the exact same Xib in another project, it works just fine… what is wrong with my actual project?
Please cross check that you declared
UIScrollViewDelegate at .h file or not..
At .m File
#synthesize scrollViewContent;
Hope it may help you...

UIScrollView not scrolling after changing from regular View

I have a xib with a View, I changed the View class to be UIScrollView.
Now I have set contentSize to some big number (2000, 2000).
Here is my code:
This allows talking to my scrollview without casting every time:
- (UIScrollView *)scrollView {
return (UIScrollView *)self.view;
}
This I do in viewDidLoad:
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 2600);
self.scrollView.scrollEnabled = YES;
I know viewDidLoad is getting called fine. But the scrollView is not reacting. I don't have any touch responders or anything that can absorb touches.
For this, first set delegate of scrollView inside your xib files then create an IBIoutlet for your scrollview. Remind that scrollView should connect with its refrencing outlet then Assign a propertyy as Strong to your scrollView.
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
and synthesize it.
#synthesize scrollView;
then try to set contentSize.
scrollView.delegate=self;
scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 2600);
scrollView.scrollEnabled = YES;
I hope it works for you.
I have found a problem, I was setting superview too small.

Resources