UIScrollView Cutting Off Bottom Content - ios

I'm having an extremely sad time trying to get my scrollView to display content correctly.
For one page it seems to show a heap of blank content at the bottom and for another it cuts off before reaching the bottom... extremely sad. I've set the constraints of the scrollView to 0 for each side.
Xcode screenshot
Screenshot of all the space
I've been playing around with trying to set the contentSize but that doesn't seem to do anything.
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)
print("Width: \(self.view.bounds.size.width) Height: \(self.view.bounds.size.height) scrollView: \(self.scrollView.contentSize)")
// prints -> Width: 375.0 Height: 667.0 scrollView: (375.0, 667.0)
}

Hard to tell what it may be with only the screenshot, but I have some suggestions. Select the ScrollView, then the ruler and:
Check if the indicator insets are all zeros.
In arrange select fill container horizontally and fill container vertically.
Try to change the height value of the height to check if it is set bigger than it needs to be.
Below a screenshot of what you should see

Related

Scroll UIView to expand into iPhone X top notch

I have the following layout:
UIImageView
UIView (with UILabel)
UITableView
As the tableView is scrolled up, the height of the imageView is decreased before actually scrolling the tableView. The following code is used for that:
let headerImageViewMaxHeight: CGFloat = 200
let headerImageViewMinHeight: CGFloat = UIApplication.shared.statusBarFrame.height
#IBOutlet var headerImageViewHeightConstraint: NSLayoutConstraint!
#IBOutlet var headerImageView: UIImageView!
#IBOutlet var subtitleView: UIView!
#IBOutlet var subtitleLabel: TextLabel!
private var contentOffsetDictionary: NSMutableDictionary!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.isKind(of: UICollectionView.self) {
let horizontalOffset: CGFloat = scrollView.contentOffset.x
let collectionView: UICollectionView = scrollView as! UICollectionView
contentOffsetDictionary.setValue(horizontalOffset, forKey: collectionView.tag.description)
} else if scrollView == tableView {
let y: CGFloat = scrollView.contentOffset.y
let newHeaderImageViewHeight: CGFloat = headerImageViewHeightConstraint.constant - y
if newHeaderImageViewHeight > headerImageViewMaxHeight {
headerImageViewHeightConstraint.constant = headerImageViewMaxHeight
} else if newHeaderImageViewHeight < headerImageViewMinHeight {
headerImageViewHeightConstraint.constant = headerImageViewMinHeight
} else {
headerImageViewHeightConstraint.constant = newHeaderImageViewHeight
scrollView.contentOffset.y = 0
}
}
}
The following two images shown the current states of scrolled down or up:
Scrolled down (initial state).
Scrolled up.
As you can see, initially the grey bar saying To Table -> Table 1 is scrolled down and is about 60 high.
When it's scrolled up, it scrolles until the safeArea. What I want to achieve is that once it reaches the safe area, it continues scrolling up into the safeArea (top notch), while keeping the text in exactly the same place (topSpace to safeArea of the text should stay the same). So, basically growing the UIView to go into the safeArea.
This image shows the ViewController layout.
Header View can be ignored, as that is aligned to the top of the viewController, but no constraints to anything else than superView.
TopSpace of the view in question, is 0 to the UIImageView.
Changing headerImageViewMinHeight to 0, makes it scroll up to the actual top of the screen, without expanding it. So this seems like a good start, but needs some extra logic or constraints.
As the UIView doesn't have a specific height constraint, changing its UILabel's top space from = 16 to => 16, there's the warning of missing Y constraint or height.
Otherwise that, together with UILabel's top space to the viewController's safeArea of => 8 sounds like it could work.
Any ideas are welcome.
EDIT: The following picture basically shows what I want, except that here the UILabel's top is not aligned to the safe area.
What this picture shows is achieved by changing headerImageViewMinHeight to 0.
Add constriant
Uncheck constraint to margin
double click on Align bottom/ Align top
click on last baseline (for bottom)/ first baseline (for top constrraint)
DONE

UIStackview fill proportionally in a UITableviewCell takes incorrect frame

Adding proportional fill setting in a UIStackview won't let the view stretch properly. Is this the expected behaviour?
Fill proportionally' distribution type works with intrinsic content size.
So if our vertical stack(height say 600) view has 2 views, ViewA (intrinsic content height 200) and ViewB(intrinsic content height 100), the stack view will size them to ViewA(height 400) and ViewB(height 200).
Here in IB what you see is not what you get.
Dragging to make frames change is useless. Just run the app.
You will see the expected behaviour only when the child views somehow get the intrinsic/constrained height.
How it looks in IB Here the top stack view has views constrained to be of height minimum 10 and 30, i.e. ration 1:4.
What we really get
Top stack view is what we had expected to look like. View with height in ratio 1:4. And bottom one with ratio 1:1, not expected.
You can fix this by creating a custom view
class CustomHeightView: UIView {
var height = 1.0
override public var intrinsicContentSize: CGSize {
return CGSize(width: 0.0, height: height)
}
}
Change the class of your UIView to CustomHeightView
So in the Controller create an outlet for the UIViews
#IBOutlet weak var header_one: CustomHeightView!
#IBOutlet weak var header_two: CustomHeightView!
Then in your viewDidLoad set the proportion the way you want it
override func viewDidLoad() {
super.viewDidLoad()
header_one.height = 1.8
header_two.height = 1.2
}

UIScroll View Not Working As Expected

I have a scene where I just want the scroll to be vertical not horizontal. I have tried to program it to disable but that doesn't seem to work. I also run into the issue where it isn't auto resizing to different phone screens. Im kinda new at this and I'm just really stuck. Any help?
Disable Code:
#IBOutlet var scrollview: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scrollview.contentSize.height = 800
scrollview.contentSize.width = 0
I think problem is with this line
scrollview.contentSize.width=0
Try to set width equal to screen width like this,
scrollview.contentSize.width=[UIScreen mainScreen].bounds.size.width;
Scrollview will scroll horizontally when it's contentSize.width is greater than viewcontroller's width.
Hope it will solve the issue.
I think you are not applying constraints on UIScrollView properly now first of all you have to properly add constraint on scrollview and no need to set contentsize from code.
http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/
Hope this tutorial will help you better understand the ScrollView
var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView = UIScrollView()
self.scrollView.contentSize = CGSizeMake(1000, 1000)
self.view.addSubview(scrollView)
}

My code with scrollview is not working?

I am using swift to get my scrollview going the structure of my elements is as shown
The code that i am using in my view controller is
import UIKit
class scrollview: UIViewController {
#IBOutlet weak var scroller: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scroller.userInteractionEnabled=true
scroller.contentSize=CGSizeMake(scroller.frame.size.width, scroller.frame.size.height)
But i am not able to make my page scroll can anyone help me out with this am i missing any constrains or something wrong with my code?
scroller.contentSize=CGSizeMake(should be total width of the labels not scroll view width, should be total height of the labels not scrollview height)
contentsize should be greater than frame size for scrolling.
In order for UIScrollView to scroll, the content size must be greater than its frame size. If, for example, you want to scroll vertically, it has to be true that scrollView.contentSize.height > scrollView.frame.size.height.

UIScrollView not scrolling in Swift

My UIScrollView won't scroll down. I don't know why. I already followed Apple documentation regarding to this issue.
#IBOutlet weak var scroller: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
scroller.scrollEnabled = true
// Do any additional setup after loading the view
scroller.contentSize = CGSizeMake(400, 2300)
}
You need to set the frame of your UIScrollView so that it is less than the contentSize. Otherwise, it won't scroll.
Also, I would recommend that you add the following to your viewDidLoad method:
scroller.contentSize = CGSize(width: 400, height: 2300)
If you are using AutoLayout
Set content size in viewDidAppear which works for me.
override func viewDidAppear(_ animated: Bool) {
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height+300)
}
Alot of the time the code is correct if you have followed a tutorial but what many beginners do not know is that the scrollView is NOT going to scroll normally through the simulator. It is suppose to scroll only when you press down on the mousepad and simultaneously scroll. Many Experienced XCode/Swift/Obj-C users are so use to doing this and so they do not know how it could possibly be overlooked by beginners. Ciao :-)
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
// Do any additional setup after the view
}
override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 800)
}
This code will work perfectly fine as long as you do what I said up above
Do not give fix height to scroll view and always give top of first subview to scrollview and bottom of last subview to scrollview. By this way scroll view will automatically grow as per the size of contained subviews. No need to give contentSize to the scrollview.It will work for small as well as large size iPhone.
Swift 3.0 version
scroller.contentSize = CGSize(width: scroller.contentSize.width, height: 2000)
If you are using autolayout, then the contentSize property stops working and it will try to infer the content size from the constraints. If that is the case, then your problem could be that you are not defining the necessary constraints to the content view so that the scrollview can infer the content size.
You should define the constraints of your content view to the top and bottom edges of the scrollview.
If you are using Storyboard:
Put your Content view inside the UIScrollView
Add top, bottom, left and right constraints with the scroll view
Add equal heights and widths constraints
For a vertical scroll set the Equal Heights Constraint priority to 250. For a horizontal scroll set the Equal Widths Constraint priority to 250
In my case, I used UIStackView inside UIScrollView.
Added some views-elements from code to stackview.
It won't scroll.
Fixed it by setting stackview's userInteractionEnabled to false.
The problem could be that your scrollView doesn't know its contentSize like stated above, but the fix is easier than what the above answers are. Like Carlos said but I will elaborate more. If you want your scrollView to scroll vertically(up & down), make your contentView which is in the hierarchy of the scrollView equal width to the ViewController and give it a height constraint that works for your project i.e. 700. For the opposite(horizontally) make the height equal to the ViewController and the width some big number that works for your project.
FWIW, I found that I needed to use sathish's solution from above, though it was insufficient to effect the intervention in viewDidAppear alone. I had to instead make the adjustment for every new content assignment:
func display(pattern: Pattern) {
let text : NSAttributedString = pattern.body()
patternTextView.attributedText = text
// Set the size of the view. Autolayout seems to get in the way of
// a correct size calculation
patternTextView.contentSize = CGSize(width: 348, height: 620)
}
The manifest constants (yeah, I know, yuk, but it makes it easier to understand here) are from the autolayout spec.
It worked for me. In Size Inspector
Layout = Translates Mask into constraints.
Autoresizing = all click.
For Swift 5.6 and iOS 15:
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
let subView: UIView = UILabel()
subView.text = String(repeating: "MMMMMMM ", count: 100)
NSLayoutConstraint.activate([
subView.topAnchor.constraint(equalTo: scrollView.topAnchor),
subView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
subView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),
subView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),
// Constrain width so the label text wraps and we scroll vertically.
subView.widthAnchor.constraint(lessThanOrEqualTo: scrollView.widthAnchor),
])
Increase the content Height work for me.
I do not know it is a good solution, but you can try to set headerview to empty UITableView.
let scrollView: UIView = UIView(frame: CGRectMake(0, 0, 400, 2300))
tableView.tableHeaderView = scrollView

Resources