UIScrollView scrolls on all the simulators but not on my iPhone - iphone

So after figuring out how scrollView works, I've implemented it with the following code:
self.scrollView.delegate = self;
self.scrollView.userInteractionEnabled = YES;
CGRect view = CGRectMake(0, 0, 320, 750);
self.scrollView.contentSize = view.size;
The above code works as intended on ALL simulators in Xcode 6. However, when I run it my phone (iphone4s on ios7), the scroll does not function at all. Are people experiencing the same problems since the new release? Or am I missing something I've learned from the documentation?

Had the same issue here. Just need to resize the scrollview's frame size in viewDidLayoutSubviews which overrides auto layout.
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[scrollView setContentSize:CGSizeMake(320, 2600)];
// Adjust frame for iPhone 4s
if (self.view.bounds.size.height == 480) {
scrollView.frame = CGRectMake(0, 0, 320, 436); // 436 allows 44 for navBar
}
}

In AutoLayout
In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to the left edge of its superview, you’re really pinning it to the minimum x-value of the superview’s bounds. Changing the bounds origin of the superview does not change the position of the view.
The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom, and right edges within a scroll view now mean the edges of its content view.
The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the scroll view. (This should not be confused with the intrinsicContentSize method used for Auto Layout.) To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its subtree.
Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.
Here are two examples of how to configure the scroll view, first the mixed approach, and then the pure approach
Mixed Approach
Position and size your scroll view with constraints external to the scroll view—that is, the translatesAutoresizingMaskIntoConstraints property is set to NO.
Create a plain UIView content view for your scroll view that will be the size you want your content to have. Make it a subview of the scroll view but let it continue to translate the autoresizing mask into constraints:
- (void)viewDidLoad {
UIView *contentView;
contentView = [[UIView alloc] initWithFrame:CGRectMake(0,0,contentWidth,contentHeight)];
[scrollView addSubview:contentView];
// DON'T change contentView's translatesAutoresizingMaskIntoConstraints,
// which defaults to YES;
// Set the content size of the scroll view to match the size of the content view:
[scrollView setContentSize:CGSizeMake(contentWidth,contentHeight)];
/* the rest of your code here... */
}
Create the views you want to put inside the content view and configure their constraints so as to position them within the content view.
Alternatively, you can create a view subtree to go in the scroll view, set up your constraints, and call the systemLayoutSizeFittingSize: method (with the UILayoutFittingCompressedSize option) to find the size you want to use for your content view and the contentSize property of the scroll view
Pure Auto Layout Approach
To use the pure autolayout approach do the following:
Set translatesAutoresizingMaskIntoConstraints to NO on all views involved.
Position and size your scroll view with constraints external to the scroll view.
Use constraints to lay out the subviews within the scroll view, being sure that the constraints tie to all four edges of the scroll view and do not rely on the scroll view to get their size.
A simple example would be a large image view, which has an intrinsic content size derived from the size of the image. In the viewDidLoad method of your view controller, you would include code similar to the code shown in the listing below:
- (void)viewDidLoad {
UIScrollView *scrollView;
UIImageView *imageView;
NSDictionary *viewsDictionary;
// Create the scroll view and the image view.
scrollView = [[UIScrollView alloc] init];
imageView = [[UIImageView alloc] init];
// Add an image to the image view.
[imageView setImage:[UIImage imageNamed:"MyReallyBigImage"]];
// Add the scroll view to our view.
[self.view addSubview:scrollView];
// Add the image view to the scroll view.
[scrollView addSubview:imageView];
// Set the translatesAutoresizingMaskIntoConstraints to NO so that the views autoresizing mask is not translated into auto layout constraints.
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.translatesAutoresizingMaskIntoConstraints = NO;
// Set the constraints for the scroll view and the image view.
viewsDictionary = NSDictionaryOfVariableBindings(scrollView, imageView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
/* the rest of your code here... */
}

I did not try Vishu's answer, but what I did was update to iOS 8 so it's compatible with Xcode 6 and it worked!

Related

Scroll View not functioning IOS 7

I have a scrollview inside which i have 20 UItextviews. The scrollview is not working. I have set the following in viewdidload.
self.MainScroll.contentSize = CGSizeMake(320, 1800);
Still it doesn't scroll. However, if i give bounce vertically, it just bounces. My scrollview is a child of the main UIview of dimension 320*600. Please guide how to enable the scroll!!
There are two ways you can get the scrolling to work.
Approach 1 (with code):
1) Pin UIScrollView to the sides of its parent view, as mentioned below.
2) Set content size of your scroll view in viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews {
self.MainScroll.contentSize = CGSizeMake(320, 1800);
}
Approach 2 (pure IB, no code required):
1) Setting contentSize is not required if using AutoLayout. You need to pin your UIScrollView to the parent view as mentioned below:
2) Then add another UIView inside UIScrollView to act as a content view and pin it to the UIScrollView and move all controls inside this content view:
3) Pin content view to its parent scroll view as mentioned below:
4) Set your UIViewController's Simulated Metrics to Freeform (this is important):
5) Size your content UIView to your desired height (obviously important too):
Apple article explaining UIScrollView and AutoLayouts:
https://developer.apple.com/library/content/technotes/tn2154/_index.html
Update the content size after some delay as below.
- (void)viewDidLayoutSubviews {
[self performSelector:#selector(updateContentSize)
withObject:nil
afterDelay:0.25];
}
-(void)updateContentSize{
UIView *viewLast = [viewContent viewWithTag:100];
scrollViewAd.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, CGRectGetMaxY(viewLast.frame));
}

UIScrollView will not scroll, even after content size set

My UIScrollView is a ~4500px horizontal view that the user needs to scroll horizontally through to view the content.
I have set it up as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
sview.frame = CGRectMake(0, 0, 568, 320);
sview.contentSize = CGSizeMake(4500, 320);
[sview setScrollEnabled:YES];
}
Yet the scroll view does nothing. Is there something obvious I missed? i've tried literally every tutorial on the web.
I got similar issue. I did following modifications and the scrollView started scrolling for me:
Select to check the 'Bounce Horizontally' property for UIScrollView
in xib.
Move the code following code to viewDidAppear instead of
viewDidLoad:
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
sview.frame = CGRectMake(0, 0, 568, 320);
sview.contentSize = CGSizeMake(4500, 320);
[sview setScrollEnabled:YES];
}
I think this should help you.
I've explained it here, but there are so many answers to this problem that suggests turning off Auto Layout. That fixes the problem but that's not really the correct solution. Here's my answer:
Turning Auto Layout works, but that's not the solution. If you really need Auto Layout, then use it, if you don't need it, turn it off. But that is not the correct fix for this solution.
UIScrollView works differently with other views in Auto Layout. Here is Apple's release note on Auto Layout, I've copied the interesting bit:
Here are some notes regarding Auto Layout support for UIScrollView:
In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to
the left edge of its superview, you’re really pinning it to the
minimum x-value of the superview’s bounds. Changing the bounds origin
of the superview does not change the position of the view.
The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom,
and right edges within a scroll view now mean the edges of its content
view.
The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the
scroll view. (This should not be confused with the
intrinsicContentSize method used for Auto Layout.) To size the scroll
view’s frame with Auto Layout, constraints must either be explicit
regarding the width and height of the scroll view, or the edges of the
scroll view must be tied to views outside of its subtree.
Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints
between the view and a view outside the scroll view’s subtree, such as
the scroll view’s superview.
Apple then goes on to show example of how to correctly use UIScrollView with Auto Layout.
As a general rule, one of the easiest fix is to create a constraint between the element to the bottom of the UIScrollView. So in the element that you want to be at the bottom of the UIScrollView, create this bottom space constraint:
Once again, if you do not want to use Auto Layout, then turn it off. You can then set the contentSize the usual way. But what you should understand is that this is an intended behaviour of Auto Layout.
First of all you have to add some content to UIScrollSiew as subview for scrolling,without content on UIScrollView how can you scroll?. Here is what i did,just add UIImageView to UIScrollView as subview of size same as size of UIScrollView...
In viewDidLoad method try the following code..
-(void)viewDidLoad
{
UIScrollView *scroll=[[UIScrollView alloc] init];
scroll.frame=CGRectMake(0, 0, 320, 460);
UIImageView *imageView=[[UIImageView alloc] init];
imageView.frame=CGRectMake(0, 0, 320,460);
imageView.image=[UIImage imageNamed:#"chiranjeevi.jpeg"];
scroll.contentSize = CGSizeMake(4500, 460);
[scroll setScrollEnabled:YES];
[scroll addSubview:imageView];
[self.view addSubview:scroll];
}
I tested this code it works well.I hope this code will be helpful to you..
I assume you are adding UISrollingView in your Xib file. This will work for you.
sview.delegate = self;
sview.backgroundColor=[UIColor clearColor];
[sview setCanCancelContentTouches:NO];
sview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
sview.clipsToBounds = YES;
sview.scrollEnabled = YES;
sview.contentSize = CGSizeMake(320,570);
CGPoint topOffset = CGPointMake(0,0);
[sview setContentOffset:topOffset animated:YES];
Also, make sure to give IBOutlet connection in your Xib file.
I also faced the same issue.I added the scroll view in xib.I also added some subviews to this scroll view. The scroll view would stop scrolling after I added the subviews. The solution for this problem was in the xib for the view in file inspector Use Autolayout was checked. I unchecked it and the scroll view scrolled after adding the subviews.
The solution was uncheking the Use Autolayout in file inspector in xib.

Cannot interact with UIScrollView

Before you bash me for duplicate, please know that I have looked nearly every other method but none of them have helped. I have a long view in which I have a scroll view.
The view is 320 by 671. The scroll view has been linked to the outlet "scrollView" correctly.
The property "scrollView" has been properly declared and synthesised.
My code:
[scrollView setScrollEnabled: YES];
scrollView.contentSize = CGSizeMake(320, 671);
scrollView.clipsToBounds = YES;
scrollView.delegate = self; // I have adopted the delegate protocol in .h
So, my problem is that the view doesn't scroll, and the scroll bar doesn't even show up.
EDIT:
I resized the uiview to normal 320 by 460. I deleted the scroll view in xib and decided to add like this:
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(self.view.center.x, self.view.center.y, 320, 460)];
[scrollView setScrollEnabled: YES];
scrollView.contentSize = CGSizeMake(320, 671);
scrollView.clipsToBounds = YES; scrollView.delegate = self;
[self.view addSubview: scrollView];
OK, now what happens is when I scroll the screen, the bar comes up and I can scroll around to change the bar's position, but the actual view doesn't scroll
You need set the ContentSize of UIScrollView to the size of your CONTENT.
Do not set "ContentSize" to the size of the view. The "Content Size" should tell the size of the content within the scroll view.
Your scrollview should be 320x460 and your scrollview.contentsize should be 320x671.
You must layout your subviews "outside" of the view in IB.
EDIT:
Your layout should look like this:
http://ge.tt/api/1/files/4qGbz2N/2/blob/x675
The textview is placed outside the views frame but inside the scrollview. The scrollviews content size should be set accordingly to fit all subviews. In this case yValue should be 550 + 128

Convert UIViewController to UIScrollViewController

I am new to iPad developer,
I made one Registration form in my application, when i see my application in Portrait mode,
i am able to see whole form with no scrolling, but when i see same form in Landscape mode, i am not able to see part which is at bottom of page, for that a scrolling should be there to see bottom part.
:
In my .h file when i replace
#interface ReminderPage : UIViewController{
...
...
}
:UIViewController with :UIScrollView
and then when i add label in my .m file like this,
UILabel *Lastpaidlbl = [[[UILabel alloc] initWithFrame:CGRectMake(70 ,400, 130, 50)]autorelease];
Lastpaidlbl.backgroundColor = [UIColor greenColor];
Lastpaidlbl.font=[UIFont systemFontOfSize:20];
Lastpaidlbl.text = #"Lastpaid on :";
[self.view addSubview:Lastpaidlbl];
I am getting error on last line Property view not found on object of type classname.
i am unable to add label in my view.
Any help will be appreciated.
The question appears to be really asking how can all the components on the screen be placed inside a UIScrollView, rather than a UIView. Using Xcode 4.6.3, I found I could achieve this by simply:
In Interface Builder, select all the sub-views inside the main UIView.
Choose Xcode menu item "Editor | Embed In | Scroll View".
The end result was a new scroll view embedded in the existing main UIView, will all the former sub-views of the UIView now as sub-views of the UIScrollView, with the same positioning.
If you want to replace your UIViewController with a UIScrollView, you will have to go a bit of refactoring to your code. The error you get is just an example of that:
the syntax:
[self.view addSubview:Lastpaidlbl];
is correct if self is a UIViewController; since you changed it to be UIScrollView, you should now do:
[self addSubview:Lastpaidlbl];
You will have quite a few changes like this one to make to your code and will face some issues.
Another approach would be this:
instantiate a UIScrollView (not derive from it);
add your UIView (such as you have defined it) to the scroll view;
define the contentSize of the scroll view so to include the whole UIView you have.
The scroll view acts as a container for your existing view (you add your controls to the scroll view, then add the scroll view to self.view); this way, you could integrate it within your existing controller:
1. UIScrollView* scrollView = <alloc/init>
2. [self.view addSubview:scrollView]; (in your controller)
3. [scrollView addSubview:<label>]; (for all of your labels and fields).
4. scrollView.contentSize = xxx;
I think the latter approach will be much easier.
Please put all of your UIComponents to the UIScrollview and then it will start scrolling.
please look in to content size. please change it according to the orientation of device.
You're subclassing UIScrollView, so there is no self.view because already self is the view (of the scrollview). You dont need to subclass the scrollview, you can just embed your components in a ivar scrollview and set its contentSize (in your case, you have to enable the scrolling just when the device is in landscape mode). In interface builder you can embed the selected elements in one click, Editor-> Embed in-> scrollview.
First create scrollview
UIScrollView * scr=[[UIScrollView alloc] initWithFrame:CGRectMake(10, 70, 756, 1000)];
scr.backgroundColor=[UIColor clearColor];
[ self.view addSubview:scr];
second
change [self.view addSubview:Lastpaidlbl];
to
[scr addSubview:Lastpaidlbl];
third
set height depends on content
UIView *view = nil;
NSArray *subviews = [scr subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
CGRect frame = view.frame;
curXLoc += (frame.size.height);
}
// set the content size so it can be scrollable
[scr setContentSize:CGSizeMake(756, curXLoc)];
Finally
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight) {
self.scr.frame = CGRectMake(0, 0, 703,768);
} else {
self.scr.frame = CGRectMake(0, 0, 768, 1024);
}
return YES;
}

iphone: View on top of UIWebView?

I'm working on a browser app, and I have an address bar on top the UIWebView. On MobileSafari if you scroll down, the address bar starts to move to the top, out of the screen, and the UIWebView doesn't scroll. Only when the address bar disappears completely, it starts to scroll. I would like to have this effect in my app as well.
What's the best way to implement this?
Thanks
The only way to implement this requires iOS 5.
In iOS 5, UIWebView has an UIScrollView subview.
And use the following code:
Set a area for the address bar:
[[myWebView scrollView] setContentInset:UIEdgeInsetsMake(64, 0, 0, 0)];
Move the address bar using the scrollview delegate:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if(scrollView.contentOffset.y>=-64&&scrollView.contentOffset.y<30)
{
topBar.frame=CGRectMake(0,-44-scrollView.contentOffset.y, 320, 44);
}
else if(scrollView.contentOffset.y<-64)
topBar.frame=CGRectMake(0,20, 320, 44);//Lock the position
}
There is a way, but I am not sure if it is a bit too hacky. First search for the scrollview within the webview, then alter the contentInset and finally add the searchbar(for example) to the scrollview. The following code is just an example, I did not set any frames correctly and 40 is just a made up height for the searchbar. I am not sure if this will work in every iOS Version.
UIWebView * myWebView = [[UIWebView alloc] init]
UISearchBar * mySearchBar = [[UISearchBar alloc] init];
for (NSObject * aSubView in [myWebView subviews]) {
if ([aSubView isKindOfClass:[UIScrollView class]]) {
UIScrollView * theScrollView = (UIScrollView *)aSubView;
theScrollView.contentInset = UIEdgeInsetsMake(40, 0, 0, 0);
[theScrollView addSubview:mySearchBar];
}
}
PeakJi's solution works but is a bit laggy. A better solution would be adding an observer to the UIScrollView's content offset, something like
[scrollview addObserver:self forKeyPath:#"contentOffset"
options:NSKeyValueObservingOptionNew context:nil];
You can find more document on NSKeyValueObserving protocol at
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html
Come to think of it, it is simply a scrolling view with an address bar stuck on the top, and both the web view and the bar always move together. Now, lets say you create a scroll view and add two subviews, the address bar and the web view (one below the other). It is to be noted that the height of the web view is determined and fixed after the page has been loaded (in webViewDidFinishLoad:).
Hence, it is simply a scrolling view whose contentSize is equal to the height of the bar + the height of the web view. Now, by default the web view allows scrolling, as it has a scroll view as a subview. As only the outer scroll view should be scrolling, it is required that the web view's scrolling be turned off. For that, fetch the first subview (that's the scroll view) and disable its scrolling using:
(UIScrollView*)[myWebView.subviews objectAtIndex:0].scrollEnabled = NO;