Swift - can't make scrollview be able to scroll left? - ios

Im having an odd problem with a scrollview - I have tried doing this in a xib file and programmatically. Basically I 3 textfields that I want to be able to scroll to with my scrollview filling the whole screen.
To do this, I first created a scrollview on my xib and constrained it so it always filled the screen. I then expanded the contentsize to 3 times the size of the view so it should be able to scroll
scrollView.delegate = self
scrollView.frame = CGRectMake(0, 0, screenSize.width, screenSize.height)
scrollView.backgroundColor = UIColor.redColor()
self.scrollView.contentSize = CGSizeMake(self.view.frame.width*3, screenSize.height * (50/568))
scrollView.center = CGPointMake(self.view.frame.width * -1.5, self.view.frame.height * 0.5)
scrollView.addSubview(containerView)
view.addSubview(scrollView)
self.scrollView.delaysContentTouches = false
I have 3 textfields named search 1, 2, 3 that I then position within this scrollview like this so they are at different lengths off the screen to the LEFT -
search3.center = CGPointMake(screenSize.width * 0.5, screenSize.height * 0.45)
search2.center = CGPointMake(screenSize.width * -0.5, screenSize.height * 0.45)
search1.center = CGPointMake(screenSize.width * -1.5, screenSize.height * 0.45)
This has worked, meaning I have the first search field 2 views to the left, the other right next to it, etc
Problem is I can only scroll to the RIGHT because I can't seem to move the center of my scrollview off the left so its length expands 3 views to the right. I have tried with this -
scrollView.center = CGPointMake(self.view.frame.width * -1.5, self.view.frame.height * 0.5)
And various other methods creating the view programmatically but it sint working. This is what I get with all the things I need to scroll to far to the right -
Ive never had this. How can I make it expand the views width to the left?

Have you tried setting the scrollView's contentOffset? According to the docs, contentOffset represent:
The point at which the origin of the content view is offset from the origin of the scroll view.
If you want your scrollview to start in the middle (can scroll to the left and right) this might work for you with assumption contentView is 3 times the size of the scrollView
self.scrollView.contentOffset = CGPointMake(self.scrollView.contentSize.width/3 , 0.0f);

Related

Horizontal UIScrollView Not Fitting iPhone 5 Screen

I'm using a UIScrollView to swipe horizontally between two ViewControllers. On iPhone 6 and higher the VCs fit perfectly in the screen. However, when testing on an iPhone 5, the second VC isn't displayed entirely. The scrollView will not display all of "Page 2" (the right VC), but will fit the left VC perfectly. I have the scrollView's contentSize width set to equal 2 times the screen's width (since there are two full screen VCs).
let screenRect = UIScreen.main.bounds
var adminFrame : CGRect = pageTwo.view.frame;
adminFrame.origin.x = adminFrame.width;
pageTwo.view.frame = adminFrame;
var BFrame : CGRect = pageOne.view.frame;
BFrame.origin.x = 2 * screenRect.width;
self.scrollView.contentOffset.x = BFrame.width
self.scrollView.contentSize = CGSize(width: screenRect.width * 2, height: screenRect.height)
If I arbitrarily add to the contentSize width, then it does fit better, but is not a perfect fit nor does it seem like a good solution.

How to Center UI View when in landscape & portrait?

I having trouble centering 2 UIImages and a Layer when Orientation changes.
here is what i did to center it
_colorLayer = [CALayer layer];
CGRect frame = self.hueImageView.frame;
CGSize superviewSize = self.hueImageView.superview.frame.size;
self.hueImageView.center = CGPointMake((superviewSize.width / 2), (superviewSize.height / 2));
self.checkeredView.center = CGPointMake((superviewSize.width / 2), (superviewSize.height / 2));
self.labelPreview.center = CGPointMake((superviewSize.width / 2), (superviewSize.height / 2));
this works fine in portrait. but when i rotate the images do not go to the middle .
the project is on my github
https://github.com/RK905/NewColorPic/blob/master/NewColorPic/NEOColorPickerHSLViewController.m
just set the center from your superView to all other views. superView.center should do it. No fights with height/2 and width/2 .
If you would use constraints, you will not need to set it again. Just align the views to the center.y and center.x of the superView. No fight with orientations because the constrain center will automaticly move also

How to set content in UIScrollView to be in the middle so,user can scroll left & right in iOS

I have a question about UIScrollView.I want to set the content in the middle of UIScrollView so, user can scroll horizontally left & right easily.ContentSize of the UIScrollView should be 3 times of the content.Below is the drawing :-
|---------------------------------ContentSize of UIScrollView-------------------------------------|
|-----------content----------|
How to set it?
Thanks!
I understand you want something like that :
|----scrollVIew.frame.size.width---|
|----------------scrollVIew.contentSize.width------------------|
|-content.frame.size.width-|
in which scrollVIew.contentSize.width = 3 x content.frame.size.width.
To perform something like that, first, set your scrollview.frame:
scrollView.frame = CGRectMake(0, 0, width, height);
Then create and add content view into your scrollView and set its frame:
CGFloat contentViewWidth = 200.f; // the width of your contentView
contentView.frame = CGRectMake(contentViewWidth, 0, contentViewWidth, height);
Finally, set the content size of your scrollview:
scrollView.contentSize = CGSizeMake(contentViewWidth * 3, height);
And if you want to center the content, you can manually scroll to the middle of your scrollVIew:
[scrollView setContentOffset:CGPointMake(scrollView.contentSize.width * 0.5f - width * 0.5f, 0)];
You should use setContentOffset method. There's another useful information on the reference page.

Parallax effect with UIScrollView subviews

I'm trying to create a Parallax effect on a UIView inside a UIScrollView.
The effect seems to work, but not so well.
First i add two UIView sub-views to a UIScrollView and set the UIScrollViews contentSize.
The Views sum up and create a contentSize of {320, 1000}.
Then I implemented the following in scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat percentage = offsetY / scrollView.contentSize.height;
NSLog(#"percent = %f", percentage);
if (offsetY < 0) {
firstView.center = CGPointMake(firstView.center.x, firstView.center.y - percentage * 10);
} else if (offsetY > 0){
firstView.center = CGPointMake(firstView.center.x, firstView.center.y + percentage * 10);
}
}
These lines of code do create a parallax effect, but as the scrolling continues, the view does not return to it's original position if i scroll to the original starting position.
I have tried manipulating the views layers and frame, all with the same results.
Any Help will be much appreciated.
The problem you have is that you are basing your secondary scrolling on a ratio of offset to size, not just on the current offset. So when you increase from an offset of 99 to 100 (out of say 100) your secondary scroll increases by 10, but when you go back down to 99 your secondary scroll only decreases by 9.9, and is thereby no longer in the same spot as it was last time you were at 99. Non-linear scrolling is possible, but not the way you are doing it.
A possible easier way to deal with this is to create a second scrollview and place it below your actual scrollview. Make it non intractable (setUserInteractionEnabled:false) and modify it's contentOffset during the main scrolling delegate instead of trying to move a UIImageView manually.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[scrollView2 setContentOffset:CGPointMake(scrollView.contentOffset.x,scrollView.contentOffset.y * someScalingFactor) animated:NO];
}
But make sure not to set a delegate for the scrollView2, otherwise you may get a circular delegate method call that will not end well for you.
Scaling Factor being the key element...
...let me offer a 1:1 calculation:
Assuming 2 UIScrollView, one in the foreground and on in the rear, assuming the foreground controls the rear, and further assuming that a full width in the foreground corresponds to a full width in the background, you then need to apply the fore ratio, not the fore offset.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let foreSpan = foreScrolView.bounds.width - foreScrolView.contentSize.width
let foreRatio = scrollView.contentOffset.x / foreSpan
let rearSpan = rearScrollView.bounds.width - rearScrollView.contentSize.width
rearScrollView.setContentOffset(
CGPoint(x: foreRatio * rearSpan, y: 0),
animated: false)
}
Final effect
The two scrollers, fore and rear, each contain a UIImageView displayed at its full width:
let foreImg = UIImageView.init(image: UIImage(named: "fore"))
foreImg.frame = CGRect(x: 0, y: 0,
width: foreImg.frame.width,
height: foreScrolView.bounds.height)
foreScrolView.contentSize = foreImg.frame.size
foreScrolView.addSubview(foreImg)
let rearImg = UIImageView.init(image: UIImage(named: "rear"))
rearImg.frame = CGRect(x: 0, y: 0,
width: rearImg.frame.width,
height: rearScrollView.bounds.height)
rearScrollView.contentSize = rearImg.frame.size
rearScrollView.addSubview(rearImg)
This will scroll both images at a different speed, covering each image in full from edge to edge.
► Find this solution on GitHub and additional details on Swift Recipes.

Scale a UIView Horizontally

I'm trying to scale a view Horizontally but i'm not getting the results i expected.
view.bounds = CGRectMake(view.bounds.origin.x, view.bounds.origin.y , view.bounds.size.width * scaleX, view.bounds.size.height );
view.center = CGPointMake(view.bounds.origin.x, view.center.y);
As you can see at the code above, i want to scale the view just to the right side. This is why i changed the center of the view.
The problem is that the view stills scaling to both sides!
I did the same logic to scale another UIView vertically and got the result i expected.
Just found the problem.
when setting certer, the new point must be relative to frame, not bounds.
so, i get the code:
view.center = CGPointMake(-view.frame.origin.x, view.center.y);
Hope it helps somebody..
Thx for help
If the origin of your view's frame is in the top-left (which is the default), increasing the width of your view should scale it to the right only.
This should work:
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width * scaleX, view.frame.size.height);
You do not need to adjust the origin/center point to scale only to the right.
Try using an affine transform instead:
view.transform = CGAffineTransformMakeScale(scaleX, 1)
And then setting the center.

Resources