Change width and add a circular scroller to a UIScrollView - ios

I am trying to increase the width of the scrollbar and add a circular scroller. Shall I use an image for the circle? I do not see any property or method of UIScrollView to change the width of the scroller
I tried the following:
UIScrollView *myScroll = [[UIScrollView alloc] init];
myScroll.frame = self.view.bounds; //scroll view occupies full parent view!
//specify CGRect bounds in place of self.view.bounds to make it as a portion of parent view!
myScroll.contentSize = CGSizeMake(400, 800); //scroll view size
myScroll.backgroundColor = [UIColor grayColor];
myScroll.showsVerticalScrollIndicator = YES; // to hide scroll indicators!
myScroll.showsHorizontalScrollIndicator = YES; //by default, it shows!
myScroll.scrollEnabled = YES; //say "NO" to disable scroll
[myScroll setBackgroundColor:[UIColor redColor]];
myScroll.indicatorStyle = UIScrollViewIndicatorStyleWhite;
[self.view addSubview:myScroll];

This custom ScrollView Solved all my problems https://github.com/BasheerSience/BRScrollBar

Related

Page control on subview

I am creating a view with a subview for a tutorial screen.
I want the gray subview to be swipeable using the page control
I have implemented the example of http://www.appcoda.com/uipageviewcontroller-tutorial-intro/ but this works with whole ViewControllers and I want it to work with only the subview...
Does anyone have any idea how to implement the PageControl with the swipe gesture so that only the gray subview changes? Any good tutorial?
The grey area must be a UIScrollView with a content view containing each page of the tutorial. Set pagingEnabled to YES on your scroll view so that it will snap to each page when you scroll.
Then you need to attach an action to the page control using addTarget:action:forControlEvents: and pass UIControlEventValueChanged as the event. Then the action must be a method that tells the scroll view to move forward or back a page depending on whether the value of the page control increased or decreased. You can do this by changing the scroll view's content offset, or by telling it to scroll so that a particular rect is visible.
Finally, implement the delegate of the UIScrollView, and use the methods that tell when the scroll view stopped scrolling (you'll need a combination of the did end decelerating, did end dragging and possibly did end scrolling animation), and update the page control's value when the scroll view changes pages.
And that's all there is to it. If you need more details, read the documentation for UIScrollView, UIScrollViewDelegate and UIPageControl.
use UIView instead of ViewController
Here is a solution that works for me:
1) Create a scrollView and pageControl in your NIB or Storyboard
2) scrollView in ViewDidLoad
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleBlack; //Scroll bar style
self.scrollView.showsHorizontalScrollIndicator = NO;
//dont forget to set delegate in .h file
[self.scrollView setDelegate:self];
self.scrollView.showsVerticalScrollIndicator = YES; //Close vertical scroll bar
self.scrollView.bounces = YES; //Cancel rebound effect
self.scrollView.pagingEnabled = YES; //Flat screen
self.scrollView.contentSize = CGSizeMake(640, 30);
3) create your views you want in the scrollView and add them in an Array
//For instance, you want 3 views
UIView *ViewOne = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[ViewOne setBackgroundColor:[UIColor redColor]];
UIView *ViewTwo = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+1, self.scrollView.frame.size.height)];
[ViewTwo setBackgroundColor:[UIColor greenColor]];
UIView *ViewThree = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+2, self.scrollView.frame.size.height)];
[ViewThree setBackgroundColor:[UIColor blueColor]];
//add all views to array
NSMutableArray *viewsArray = [[NSMutableArray alloc] initWithObjects:ViewOne, ViewTwo, ViewThree, nil];
4) pageControl in ViewDidLoad
self.pageControl.numberOfPages = viewsArray.count;
self.pageControl.currentPage = 0;
self.pageControl.backgroundColor = [UIColor clearColor];
[self.pageControl setTintColor:[UIColor whiteColor]];
5) Add it all up
for(int i = 0; i < viewsArray.count; i++)
{
CGRect frame;
frame.origin.x = (self.scrollView.frame.size.width *i) + 10;
frame.origin.y = 0;
frame.size = CGSizeMake(self.scrollView.frame.size.width - 20, self.scrollView.frame.size.height);
NSLog(#"array: %#", [viewsArray objectAtIndex:i]);
UIView *view = [[UIView alloc] initWithFrame:frame];
view = [viewsArray objectAtIndex:i];
[self.scrollView addSubview:view];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width*viewsArray.count, self.scrollView.frame.size.height);
}
6) Track the scrollView and update the pageControl (DONT FORGET THE SCROLLVIEW DELEGATE)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
//int page = floor((scrollView.contentOffset.x - pageWidth*0.3) / pageWidth) + 1);
self.pageControl.currentPage = (int)scrollView.contentOffset.x / (int)pageWidth;
NSLog(#"CURRENT PAGE %d", self.pageControl.currentPage);
}
This should do the trick.
PS. Sorry for all the magic numbers.

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.

make a button that moves image

I want to make a button that moves my image one frame height up and if the button is pushed again move the image one frame height back down.
http://imageshack.us/photo/my-images/140/72197925.png/
(Illustration of the solution)
I am trying to use as little code as possible.
UIImage *image = [UIImage imageNamed:#"01bear.png"];
imageView = [[UIImageView alloc] initWithImage:image];
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:applicationFrame];
scrollView.contentSize = CGSizeMake(5760, 1);
[scrollView addSubview:imageView];
[window addSubview:scrollView];
[window makeKeyAndVisible];
scrollView.delegate = self;
scrollView.pagingEnabled = YES;
on button's touchUpInside event you need to change the:
scrollView.contentOffset = CGPointMake(X,Y);//required value to scroll the scrollview
if you only want the imageview to move, you can use:
[imageView setCenter:CGPointMake(X,Y)];//required value
Some questions:
Are you using the scroll view for other things, or just to get your image to move?
Do you want your image view to animate up, then down, or move suddenly?
A scroll view is awfully complex if all you want to do is have your view animate up, then down. To do that, you should look at the UIView class method animateWithDuration:animations: and it's variations.

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

UIView in UIScrollView does not appear

I'm trying to create a horizontally scrollable menu similar to that in this video.
For some reason the UIView doesn't appear after adding a bunch of UIButtons to it and adding it to the UIScrollView. Here's my code (it's called in -viewDidLoad of a subclass of UIViewController):
//set up scrollview
UIScrollView *designPicker = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 431, 320, 49)];
//set up a view to drop into the scroll view
UIView * buttonsView = [[UIView alloc] initWithFrame:CGRectMake(0, 431, 640, 49)];
//add buttons to scrollview
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
float runningX = designPicker.frame.origin.x;
for (i = 1; i <= 10; i++)
{
UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[tempBtn setBackgroundImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
CGRect rect = CGRectMake(runningX, designPicker.frame.origin.y, 30.0, 30.0);
tempBtn.frame = rect;
[buttonsView addSubview:tempBtn];
runningX = runningX + 35;
[tempBtn release];
}
[designPicker setContentSize:buttonsView.frame.size];
[designPicker addSubview:buttonsView];
[self.view addSubview:designPicker];
You should not add the buttons using the frame of the UIScrollView. The origin of the frame is in the superview's (superview of the UIScrollView) coordinates. You should make the buttons' frame relative to the UIView. So if you want the buttons to appear at the top of the view that you should start at (0,0).
Instead of adding scrollview as subview to your view, add view as subview of scrollview. As-
[self.scrollView addSubview:self.view];
// release scrollView as self.view retains it
self.view=self.scrollView;
[self.scrollView release];
And make sure your view should have large content size than content size of your scrollview.It worked for me.

Resources