How to create an UIScrollView from a nib file in iOs - ios

I am trying to create a scrollable view in an iOS app. If I do this programmatically, everything works fine, like in:
CODE A
- (void) loadView {
[super loadView];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
scrollView.backgroundColor = [UIColor whiteColor];
scrollView.frame = self.view.frame;
CGRect tfRect = CGRectMake(20, 70, 240, 30);
UILabel *tf = [[UILabel alloc] initWithFrame:tfRect];
tf.text = #"Some additional text!";
[scrollView addSubview:tf];
scrollView.contentSize = CGSizeMake(320.0, 1000.0)
[self setView: scrollView];
}
Unfortunately I have a rather complex view layout, so I designed it in a nib/xib. But, when I load that into nib into the scroll view ... it does not scroll.
CODE B
- (void) loadView {
[super loadView];
UIScrollView *scrollView = [[[NSBundle mainBundle] loadNibNamed:#"TOGPraiseController" owner:self options:nil] objectAtIndex:0];
scrollView.backgroundColor = [UIColor whiteColor];
scrollView.contentSize = CGSizeMake(320.0, 1000.0)
[self setView: scrollView];
}
The content loads fine, but no matter which attributes of the view I change, it never ever scrolls. If I allow bouncing, I can see, that even all elements (subviews) below the bottom are there and I can drag them into view temporarily. But then they bounce back. And scroll indicators never appear.
What am I doing wrong. Which attributes do I have to set in the UIScrollView, so that scrolling is enabled. It seems that the interface editor of XCode sets some attributes, which prohibit scrolling.

Related

Custom View AddSubview programmatically, not shown UIElements…

I do this to add a Subview from Storyboard, which is a subview from a ViewController with its own Class. (TomStatusbarController) ...it is set as CustomClass in Storyboard. I do also Constraints with Layoutformats. This works fine, but the Statusbar is just red and i see no UIElements. I get lots on constraints warnings but it worked before, when i had it as an IBOutlet, but I have to change this now.
-(void)viewDidLoad {
[super viewDidLoad];
if (self) {
self.tomCaptureStatus = [[TomStatusbarController alloc] initWithFrame:CGRectMake(0, 0, 375, 78)];
self.tomCaptureStatus.layer.bounds = CGRectMake(0, 0, 375, 78);
self.tomCaptureStatus.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
self.view.translatesAutoresizingMaskIntoConstraints = YES;
self.tomCaptureStatus.backgroundColor = [UIColor redColor];
[self.view addSubview:self.tomCaptureStatus];
[self.view superview];
}
}
So why i don't see any thing, expect my backgroundcolor?
Tom

UIScrollView is not scrolling even with setting contentSize

My UIScrollView isn't scrolling. (I'm trying to get it to scroll horizontally) I'm setting the contentSize to be (960, 300). I have set the framesize of the UIScrollView to be width:320 height:300 in the storyboard.
I have a container view inside the scroll view that has a width of 960 points.
At 320 points, I have a subview that has a background color of brown. When I scroll, I can see the brown subview, but it bounces back when I let go of the drag.
This is my viewDidLoad method:
- (void)viewDidLoad
[super viewDidLoad];
self.scrollView.scrollEnabled = YES;
[self.scrollView setFrame:CGRectMake(0,0,320,300)];
self.scrollView.contentSize = CGSizeMake(960, 300);
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 300)];
[subview1 setBackgroundColor:[UIColor brownColor]];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 960, 300)];
[containerView addSubview:subview1];
[self.scrollView addSubview:containerView];
}
Here is a sample code for create a scroll view programmatically:
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.scrollEnabled = YES;
scrollView.contentSize = CGSizeMake(960, 300);
[self.view addSubview:scrollView];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 300)];
[subview1 setBackgroundColor:[UIColor brownColor]];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 960, 300)];
containerView.backgroundColor = [UIColor greenColor];
[containerView addSubview:subview1];
[scrollView addSubview:containerView];
So, there is no issue in your code, but something wrong with your storyboard configure.
I have a few thoughts about what you are trying to accomplish. I don't know how old is your code, but today we have many better ways to work with scrollview and they don't include setting up the intrinsic size or fame.
Well, despite my doubt about the objective of the code, I tried to run it here, using storyboard, a single view, a default configured scrollView and the experiment went well, your code actually works, I think maybe you have some problem with your scrollView. I know this will sound weird but did you checked if the scrollView has the property "Scrolling Enabled" checked?
If you can give me more information about this issue, I can help you.

UIScrollView setContentOffset will add a subview to the scrollview?

I happened to find that setContentOffset to a UIScrollView will cause the scrollView append a new view to its subviews. here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake((320 - 261) / 2, 50, 261, 67)];
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.bounces = NO;
scrollView.backgroundColor = [UIColor darkGrayColor];
for (int i = 0; i < 5; i ++) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * 87, 1, 87, 65)];
view.tag = i;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 30)];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.text = [NSString stringWithFormat:#"%d", i];
[view addSubview:label];
view.backgroundColor = [UIColor greenColor];
[scrollView addSubview:view];
}
scrollView.contentSize = CGSizeMake(87 * 5, 67);
NSLog(#"before scroll: count of subview is %d", scrollView.subviews.count);
CGPoint offset = CGPointMake(87, 0);
[scrollView setContentOffset:offset animated:YES];
NSLog(#"after scroll: count of subview is %d", scrollView.subviews.count);
[self.view addSubview:scrollView];
}
Before calling setContentOffset:offset, the number of subviews of the scrollView is 5. This is what I expect. After that, the number turns to be 6.
Is it working as designed? How to avoid the new subview appended?
The extra subview is the scroll indicator. If you check again in a later method, it will have gone away. Don't worry.
You can confirm this by hiding the scroll indicators (showsVerticalScrollIndicator and showsHorizontalScrollIndicator properties).
Don't try to assume things about the view hierarchy of UIKit classes. UIKit can, and does, add its own views to several things - see tableviews and their cells, a navigation controller's view and so on.

Adding UIScrollView to a UIViewController

I have a UIViewController, and I want to add a UIScrollView to it (enable scroll support), is it possible?
I know it is possible, if you have a UIScrollView to add a UIViewController to it, but I'm interested also if reverse was true, if I cann add a UIScrollView to an existing UIViewController, such that I get scrolling feature.
Edit
I think I have found an answer: Adding a UIViewController to UIScrollView
An UIViewController has a view property. So, you can add a UIScrollView to its view. In other words, you can add the scroll view to the view hierarchy.
This is can achieved by code or through XIB. In addition, you can register the view controller as the delegate for your scroll view. In this way, you can implement methods for performing different functionalities. See UIScrollViewDelegate protocol.
// create the scroll view, for example in viewDidLoad method
// and add it as a subview for the controller view
[self.view addSubview:yourScrollView];
You could also override loadView method for UIViewController class and set the scroll view as the main view for the controller you are considering.
Edit
I created a little sample for you. Here, you have a scroll view as a child of the view of a UIViewController. The scroll view has two views as children: view1 (blue color) and view2 (green color).
Here, I suppose you can scroll in only one direction: horizontally or vertically. In the following, if you scroll horizontally, you can see that the scroll view works as expected.
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 2, self.view.bounds.size.height);
[self.view addSubview:scrollView];
float width = 50;
float height = 50;
float xPos = 10;
float yPos = 10;
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(xPos, yPos, width, height)];
view1.backgroundColor = [UIColor blueColor];
[scrollView addSubview:view1];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width + xPos, yPos, width, height)];
view2.backgroundColor = [UIColor greenColor];
[scrollView addSubview:view2];
}
If you need to scroll only vertically you can change as follows:
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height * 2);
Obviously, you need to rearrange the position of view1 and view2.
P.S. Here I'm using ARC. If you don't use ARC, you need to explicitly release alloc-init objects.

UIScrollView won't stay in place after user finishes scrolling

Within my UIView, I have a UIScrollView which fills the first view, so than when the content is bigger than the iPhone screen size, the user can scroll the page down. It works well, but when the user finishes the scroll movement - i.e. removes his fingers, the page snaps back into it's original position. Obviously that is not what I want, how can it be avoided?
Here is the relevant code in the UIView class which declares and uses the UIScrollView class.
#implementation TestView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
}
CGRect scrollViewFrame = CGRectMake(0, 0, 320, 460);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
scrollView.canCancelContentTouches=NO;
[self addSubview:scrollView];
CGSize scrollViewContentSize = CGSizeMake(320, 500);
[scrollView setContentSize:scrollViewContentSize];
CGRect rectForBigRedSquare = CGRectMake(50, 50, 200, 200);
UILabel *redSquare = [[UILabel alloc] initWithFrame:rectForBigRedSquare];
[redSquare setBackgroundColor:[UIColor redColor]];
[scrollView addSubview:redSquare];
return self;
}
An additional question is this: how is it possible to make it such that the user can only scroll down, that is to see content at the bottom which was out of view, but not to scroll up so that there is space before the start of the content. In
Basically you just have to set contentSize of your scrollview according to the contents.
CGSize scrollViewSize = CGSizeMake(newWidth, newHeight);
[self.myScrollView setContentSize:scrollViewSize];
Okay, the easiest way to get this scrollview working as you desire is to ensure that content size of the scrollview is identical to the frame size of the content you wish to scroll.
You can achieve this by having a content view into which you add all the views you wish to be visible and then add that content view to the scrollview while ensuring that the content size of the scrollview is set to the content view's frame size.
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
UIView* contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1280, 460)];
UIView* redView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[redView setBackgroundColor:[UIColor redColor]];
[contentView addSubview:redView];
[redView release];
UIView* blueView = [[UIView alloc] initWithFrame:CGRectMake(960, 0, 320, 460)];
[redView setBackgroundColor:[UIColor blueColor]];
[contentView addSubview:blueView];
[blueView release];
CGSize contentViewSize = contentView.frame.size;
[scrollView addSubview:contentView];
[scrollView setContentSize:contentViewSize];
[contentView release];
[self addSubview:scrollView];
The app I was working on had similar symptoms. The user could scroll down but on release the view would snap back to the initial position. The page was set up as follow:
[VIEW]
[SAFE AREA]
[SCROLL VIEW]
[CONTENT VIEW]
I strongly suspect that a combination of Auto-Layout and manual constraints caused by several adjustment iterations was causing the issue. To resolve this all constraints where removed from the View.
The Scroll View was assigned the following constraints:
Scroll View.leading = Safe Area.leading
Scroll View.top = Safe Area.top
Scroll View.trailing= Safe Area.trailing
Scroll View.bottom = Safe Area.bottom
The Content View was then assign the following constraints
ContentView.Leading = Scroll View.Leading
ContentView.top = Scroll View.top
ContentView.centerX = ScrollView.centerX
The Content View was also given the following self constraint
height = 1000

Resources