So I have my UIScrollView,
var myScrollView = UIScrollView(frame:theFrame)
and I would like to disable vertical scrolling. Does anyone know how to implement this using Swift?
Another way to do this is to set the height to 1.0
scrollView.contentSize = CGSizeMake(theFrame.size.height, 1.0)
Try this. This sets the content size to the height of the frame so it disables vertical scrolling because it can display the whole size.
let scrollSize = CGSizeMake(theFrame.size.height, yourWidth)
myScrollView.contentSize = scrollSize
Related
I have subview in a scrollview and after I remove some subview from the bottom there is a blank space and the scroll view still keeps height, not resizing. How to fix this?
Scrollview's contentHeight & contentWidth is calculated from its subviews(if used auto layout). If autolayout is not used then you need to set its content size.
So whenever you are adding or removing subviews in scrollview you need to take care of its contentHeight and contentWidth.
If you're using auto layout, you need to add constraints to newly added view in such a way that scroll view can calculate its contentHeight from it.(in auto layouts you don't need to explicitly set the content height to scroll view)
If you're using frame base layout, you need to set the contentHeight explicitly to the scroll view. In frame base layout, you need to take care of scrollviews content size.
Why is there blank space in scrollview?
When a subview is removed from scrollview, its content size need to be adjusted. It means it is not able to calculate its content size.
you can use this line
self.scrollView.contentSize = CGSize(width: self.view.frame.width, height: (YOURVIEW) - (THEREMOVEDVIEW))
I recommend you that you must save the height before remove view for later you can adjust.
UIScrollView doesn't know the height of its content automatically. You must calculate the height and width for yourself like below:
scrollView.contentSize = CGSize(width: self.view.frame.size.width, height: 700)
note: change width and height as you want.
you can try this also:
let content: CGRect = scrollView.subviews.reduce(into: .zero) { rect, view in
rect = rect.union(view.frame)
}
scrollView.contentSize = content.size
I am working with Swift 4.0 where I want UITableview with both vertical and horizontal scroll.
I have set contentSize of my UITableview. If I change the frame of UITableview programmatically then contentSize of UITableview is not working.
If the frame is same as it is set using autolayout then the contentSize of UITableview is working fine.
Below is the code I have tried :
let height : CGFloat = CGFloat((self.transactionArr.count*60)+70)
let width = self.view.frame.size.width*2
self.tblWidth.constant = self.view.frame.size.width
self.view.updateConstraintsIfNeeded()
self.tableView.contentSize = CGSize(width: width, height: height)
Don't hack UITableView - it is designed to scroll only vertically. Check out UICollectionView instead, it is designed for both vertical and horizontal scrolling (although you can make it scroll just one way if that's your need) - docs, or a tutorial.
You can put your tableview in a ScrollView. Make sure your ScrollView size is the same with tableview.
set your ScrollView width bigger than your container view and you can scroll your tableview horizontally.
I am very new to Swift and developing on ios but I cannot find a way to make the UIScrollView to scroll down and stay down. I have been trying tons of tutorials over this and still nothing. I have a ContentView element inside of my ScrollView element. This ContentView has all of my boxes that I want it to scroll through but it does not scroll. It does though bounce if that makes any difference...can anyone send me in the right direction?
Try setting the contentSize in viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 1500)
}
I finally figured it out after 2 days and it was very simple. All I did was set the scrollView to the size of the screen but then set the content view height at 1500px and it started working. Thanks everyone!
Sounds like uou may not have set the contentSize for your scroll view. To do that if you're not using Auto layout:
scrollView.contentSize = // The size of your content.
If you are using Auto layout you need to make sure you have NSLayoutConstraints from each edge of your content to each corresponding edge of your UIScrollView. By doing this the content size of your UIScrollView will be set automatically.
Hope that helps.
Just wanted to add a note to FreeTheStudentsAnswer in case anyone had a similar issue to me - I set the scrollView to the size of the screen and then set the content view height at a larger value and it started working only when I set these in the viewDidAppear instead of viewDidLoad. Not sure if that will help anyone, but that fixed my issue
In scrollview, scroll happens only if the scrollview has enough space to scroll its content.
You said the scrollview and its content view have the same dimensions.
Then it won't scroll.
Scrollview.contentSize should be at least double the size of scrollview if you want it to scroll.
Hint: scrollview dimension should not be greater than the iPhone screen size. And scrollview content size should be greater than the scrollview.
Scroll view scrolls through its contentview.
SWIFT 4.0 Update
#IBOutlet weak var myScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
myScrollView.alwaysBounceVertical = true
myScrollView.alwaysBounceHorizontal = true
myScrollView.isScrollEnabled = true
myScrollView.contentSize = CGSize(width: 375, height: 1000)
}
Try This
1.scrollView.bounds = YES;
2.scrollView.contentSize = CGSize(width: self.view.frame.size.width, height: YourContentView.frame.size.height);
I would like to know how to implement parallax scrolling similar to Yahoo News Digest app. In which when user scroll horizontally background image scrolls in a different speed with the paging is enabled.
May be they do it with a ScrollView with a background view. Not exactly sure. Hint to implement such scrolling would be great. I have checked similar questions but couldn't find the answer I was looking for.
I've done this before with 2 scrollviews.
You have the main detail scroll view and then the parallax scroll view behind it (or wherever you want it).
Then you become the delegate of the detail scrollview.
In the method scrollView:didScroll you can then adjust the scroll of the parallax view.
If you're just doing the x axis then you want something like this...
CGFloat detailMaxOffset = self.detailScrollView.contentSize.width - CGRectGetWidth(self.scrollView.frame);
CGFloat percentage = self.detailScrollView.contentOffset.x / maxOffset;
CGFloat parallaxMaxOffset = self.parallaxScrollView.contentSize.width - CGRectGetWidth(self.parallaxScrollView.frame);
[self.parallaxScrollView setContentOffset:CGPointMake(percentage * parallaxOffset, 0);
This will set the scrollviews content offset "percentage" to be the same on each.
To get the parallax effect you just need to make the contentSize of each scrollview different.
If the parallax scroll view has a bigger content size than the detail scroll view it will scroll faster. If it has a smaller content size it will scroll slower.
Here is the answer. I subclass it from uitableview so that data can be reusable and wrap it in a uiview. https://github.com/michaelhenry/MHYahooParallaxView
Thanks,
Kel
100% working and dam easy
Take a view on imageview exactly size of image view.
by default alpha for view set 0.
//MARK: Scroll View Delegate methods
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(#"X: %f Y: %f",scrollView.contentOffset.x,scrollView.contentOffset.y);
CGFloat scrollY = _mainScrollView.contentOffset.y;
CGFloat height = _alphaView.frame.size.height;
CGFloat alphaMonitor = scrollY/height;
_alphaView.alpha = alphaMonitor;
}
Swift 3
Here's how I got a parallax effect to work in Swift 3 for a vertical scroll in a tvOS app.
In ViewDidLoad():
parallaxScrollView.delegate = self
detailScrollView.delegate = self
And following:
override func viewDidLayoutSubviews() {
self.detailScrollView!.contentSize = CGSize(width: 1920, height: 2700)
self.parallaxScrollView?.contentSize = CGSize(width: 1920, height: 3000)
}
//// THE SCROLL VIEW
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Parallax effect
let detailMaxOffset = self.detailScrollView.contentSize.height - self.detailScrollView.frame.height;
let percentage = self.detailScrollView.contentOffset.y / detailMaxOffset
let parallaxMaxOffset = self.parallaxScrollView.contentSize.height - self.parallaxScrollView.frame.height;
let parallaxOffset = CGPoint(x:0,y:(percentage * parallaxMaxOffset))
self.parallaxScrollView.setContentOffset((parallaxOffset), animated: false)
}
I have a UIView like iPhone's Springboard. I have created it using a UIScrollView and UIButtons. I want to disable horizontal scrolling on said scrollview. I want only vertical scrolling. How do I accomplish this?
You have to set the contentSize property of the UIScrollView. For example, if your UIScrollView is 320 pixels wide (the width of the screen), then you could do this:
CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];
The UIScrollView will then only scroll vertically, because it can already display everything horizontally.
UPDATED: (After #EranMarom pointed out on his comment)
You can stop horizontal scrolling or vertical scrolling in the ScrollViewDelegate Method.
Here it is how,
Stops Horizontal Scrolling:
If you want to scroll horizontally, then you need to increase the contentOffset.x. Preventing that stops the scrollview scroll in horizontal direction.
- (void)scrollViewDidScroll:(UIScrollView *)sender {
sender.contentOffset.x = 0.0
}
Stops Vertical Scrolling:
If you want to scroll vertically, then you need to increase the contentOffset.y. Preventing that stops the scrollview scroll in vertical direction.
- (void)scrollViewDidScroll:(UIScrollView *)sender {
sender.contentOffset.y = 0.0
}
Above code prevents the changes in x and y of a scrollview contentOffset and it leads to stop the scrolling in scrollViewDidScroll: method.
since iOS7 use
self.automaticallyAdjustsScrollViewInsets = NO;
//and create you page scroller with 3 pages
self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
[self.pageView setShowsVerticalScrollIndicator:NO];
[self.pageView setPagingEnabled:YES];
[self.view addSubview:self.pageView];
Swift solution
Create two outlets, one for your view and one for your scroll view:
#IBOutlet weak var myView: UIView!
#IBOutlet weak var scrollView: UIScrollView!
Then in your viewDidLayoutSubviews you can add the following code:
let scrollSize = CGSize(width: myView.frame.size.width,
height: myView.frame.size.height)
scrollView.contentSize = scrollSize
What we've done is collected the height and width of the view and set the scrollViews content size to match it. This will stop your scrollview from scrolling horizontally.
More Thoughts:
CGSizeMake takes a width & height using CGFloats. You may need to use your UIScrollViews existing height for the second parameter. Which would look like this:
let scrollSize = CGSize(width: myView.frame.size.width,
height: scrollView.contentSize.height)
In my case, with Swift 4.2 you can use:
Disable vertical scroll:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.contentOffset.y = 0.0
}
Disable horizontal scroll:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.contentOffset.x = 0.0
}
In my case the width of the contentView was greater than the width of UIScrollView and that was the reason for unwanted horizontal scrolling. I solved it by setting the width of contentView equal to width of UIScrollView.
Hope it helps someone
You can select the view, then under Attributes Inspector uncheck User Interaction Enabled .
Introduced in iOS 11 is a new property on UIScrollView
var contentLayoutGuide: UILayoutGuide
The documentation states that you:
Use this layout guide when you want to create Auto Layout constraints related to the content area of a scroll view.
Along with any other Autolayout constraints that you might be adding you will want to constrain the widthAnchor of the UIScrollView's contentLayoutGuide to be the same size as the "frame". You can use the frameLayoutGuide (also introduced in iOS 11) or any external width (such as your superView's.)
example:
NSLayoutConstraint.activate([
scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])
Documentation:
https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide
#Gulfam Khan's answer is the correct one, I am adding imagery to help the concept get more visibility.
When we set the contentView to have equal width's with the Scroll view, if the multiplier is even slightly greater than 1:1, then we will get horizontal scrolling.
Here is what it produces:
If you do not want horizontal scrolling, you most likely do not have horizontal content that exceeds the width of the superview.
Therefore if you ensure the contentView width does not exceed the width of the scroll view, that will automatically resolve the problem as UIKit recognizes there is no horizontal content to scroll to. Like so:
Now you should only see vertical:
I had the tableview contentInset set in viewDidLoad (as below) that what causing the horizontal scrolling
self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);
Check if there are any tableview contentInset set for different reasons and disable it
I struggled with this for some time trying unsuccessfully the various suggestions in this and other threads.
However, in another thread (not sure where) someone suggested that using a negative constraint on the UIScrollView worked for him.
So I tried various combinations of constraints with inconsistent results. What eventually worked for me was to add leading and trailing constraints of -32 to the scrollview and add an (invisible) textview with a width of 320 (and centered).
Try This:
CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];
Disable horizontal scrolling by overriding contentOffset property in subclass.
override var contentOffset: CGPoint {
get {
return super.contentOffset
}
set {
super.contentOffset = CGPoint(x: 0, y: newValue.y)
}
}
Once I did it replacing the UIScrollView with a UITableView with only 1 cell, it worked fine.
Use this single line.
self.automaticallyAdjustsScrollViewInsets = NO;