My ScrollView is not scrolling vertically - swift

I'm writing an app in Xcode 9 with Swift 4 and I've added a UIScrollview to a view which is intended to show a jPeg which is 3030 pixels in height. I've added the scrollview to my view and assigned the delegate in Outlets in IB. I've attached the IBOutlet called scrollView to the UIScrollview and added a UIImageView with the jPeg to the UIScrollview. I've set the size of the UIScrollView to 375W and 620H and then set the UIImageView to 375W and 3030H. this should complete the work in Interface builder.
In the Controller I've added UIScrollViewDelegate to the Class and added the code below to ViewDidLoad
//scrollView.delegate = self
scrollView.contentSize = CGSize(width: 375, height: 3040)
I've commented out the delegate line as I've done that in IB. When I run the app, the screen comes upon with the image but when I try to scroll it barely scrolls more than one screen. What have I missed?

You need to add a UIView inside your scrollview and then add that view top/bottom/leading/trailing 0 to scrollview then add your image view inside view and add image view bottom constraint to that view, So your scroll view will work properly.
Please refer below image for more details.

You have to place your scroll view inside a UIView and another UIView inside your scroll view.
Outer view Constraints: Leading,trailing,top and bottom - 0
Scroll view Constraints: Leading,trailing,top and bottom - 0
Inner view Constraints: Leading,trailling and top to Superview, Equal width to Outer view , Bottom space to -250 and Height equals 900(Height of your content)
Set your contentsize now.

You can implement as below image screen shots
//Height Constant of image
#IBOutlet weak var ConstHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 11.0, *) {
self.scrollView.contentInsetAdjustmentBehavior = .never
}else{
self.automaticallyAdjustsScrollViewInsets = false
}
//You can change height on here too
self.ConstHeight.constant = 800
}

Related

Controls at the bottom of UIScrollView not working

The UIButton in the scrollView is visible, but not accessible. I am using Constraints.
My UI structure is this:
- UIView
- scrollView: UIScrollView
- contentView: UIView
- UIButton
- UIButton
- UIButton
- ....
- UIButton
I've already tried to set the contentSize of the scrollView. And the height of the contentView. Next to that I've tried to uncheck the checkbox Adjust Scroll View Insets in the storyboard of that ViewController without any luck. I've also set the priority of the Align Center Y to 250, and the priority bottom space to 250 of the contentView.
func updateScrollViewSize() {
var contentRect = CGRect.zero
for view in contentView.subviews {
contentRect = contentRect.union(view.frame)
}
contentRect.size = CGSize(width: scrollView.contentSize.width, height: contentRect.height + 50)
scrollView.contentSize = contentRect.size
contentView.frame.size = contentRect.size
contentView.layoutIfNeeded()
}
The button I try to reach has a Y value of: 1030.0
The height of the contentView is: 871.0
Step-by-step:
Add a scroll view to your view, background color red, constrain it 20-pts on each side:
Add a UIView as your "content view" to the scroll view (green background to make it easy to see), constrain it 0-pts on each side, constrain equal width and equal height to the scroll view. Important: change the Priority of the Height constraint to 250!
Add a UILabel to the contentView, constrain it 30-pts from the top, centered horizontally:
Add another label to the contentView, constrain it 300-pts from the first label, centered horizontally:
Add a UIButton to the contentView, constrain it 30-pts from the bottom, centered horizontally:
Now add a vertical constraint from the bottom of the second label to the top of the button, and set it to 400-pts:
As you see, this pushes the button off-screen past the bottom of the scroll view.
Run the app. You will be able to scroll down to see the button, and you'll be able to tap it.
Absolutely no code needed!
If you use AutoLayout, you don't needed to install frames manually.
You can try install constraints properly and content size will be right in this case and you won't have to install content size manually.
If you achieve this, I guess everything will work correctly.
You can follow this or this guide

Buttons outside of UIScrollView are not touchable

I'm facing an annoying problem with UIScrollView that my buttons cannot be touched if they are outside of the scroll view but I dont know how to fix it now
I have tried some ways but no helps so far
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var contentRect = CGRect.zero
for view in scrollContentView.subviews {
contentRect = contentRect.union(view.frame)
}
for view in scrollContentView.subviews {
contentRect = contentRect.union(view.frame)
}
scrollView.contentSize.height = contentRect.size.height
}
The code above just helps to make the scroll view scrollable
I also attached my sample project in this link
https://drive.google.com/open?id=19U8jecDNQbAnTFbG36KMRxHfaLLcaLDq
I strongly appreciate your advices. Thank you
You have not described your view hierarchy correctly. What you actually have is this:
Scroll view
Content view
Stack view
Buttons
The content view is what is causing the problem. Its height is pinned to the height of the view controller's main view — which is the height of the screen. But of course the stack view with its buttons is taller than the screen, in order to give you something to scroll to. So the lower part of the stack view, and the buttons at the bottom of the stack view, are below the bottom of the content view. Thus they are outside their superview. Thus they are untouchable. A view outside its superview (or its superview, or its superview, all the way up the view hierarchy) is untouchable.

Scroll in UIScrollView with tvOS

I stuck with scrolling content inside UIScrollView in my tvOS app.
I have scrollView with height = 400 and width = 400. Inside this scrollview I have non-scrollable UITextView with height = 800 and width = 400. So I want to scroll this text.
But my scroll view is not scrolled, I don't see any scrolling indicators and also my scrollView have isFocused value = false. How can I solve this problem?
p.s. update I created separate ViewController (image below).
It have black ScrollView and white view with big height with label in the middle of it. ScrollView has fixed width and height and there is no scrolling for some reason! I even didn't connect any separate class - just created it from Interface builder.
UIView isn't focusable by default (and as such in tvOS it can't be scrolled) . You have to subclass it to override canBecomeFocused:
class myUIView: UIView {
override var canBecomeFocused: Bool {
return true
}
}
Then in your example use the class myUIView instead of UIView for your long white view. Setting the right constraints you wouldn't need to design the views out of the controller view boundaries in IB either. Check this answer with the linked gist to see how to build the constraints.
I think you can use the
func gestureRecognizer (_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
method to judge the view and scroll it
According to the view you touch to do something to intercept
There is some way to fix your problem.
Please check your scrollview in storyboard, is your scrolling or vertical indicator is checked?
U can make your textview scrollable if u just want to scroll the textview content
There is problem in your constraint, you need to cleary add the height, vertical space top, vertical space bottom from your textview to your scrollview.
Hope these advice can help you
So you have to set the scrollview's content size larger than the scrollview bounds, so you should set contentsize to (400, 800), probaly in you xib

UIScrollView doesn't scroll if started from pressing on textField

I have UIScrollView with labels and textFields (screenshot).
I have calculated contentViewHeight based on number of views.
When started scrolling from image or label, scrollView scrolls perfect, but if I touch from textField and drag, scrollView didn't scroll or fire scrollViewDidScroll method.
Can somebody help me with this issue?
When the textFieldShouldBeginEditing (_ :) option is trimmed, the total size of the View will be trimmed so you have those drawbacks.
You can define the scrollView in viewdidload:
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.contentSize = CGSize(width: self.view.frame.width, height: 570)
// Do any additional setup after loading the view.
}
And using 'IQKeyboardManager' is highly recommended.

Right part of UIScrollView doesn't work in Landscape mode

Using the Interface Builder, I created a view with a UIScrollView in it.
I programmaticly add the buttons to the empty UIScrollView.
When the orientation changes, I use
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
to call a method that resets the buttons on screen.
After that, the uiScrollView-content gets a new size using setContentSize.
No matter the width of the ContentSize, I can only interact (scroll/or tap a button) on the first 320px of the screen - which is the screen width in portrait mode.
When I set the contentSize-width to 2000, I can scroll to the left, but only with my fingers on the first 320 px instead of the full 480 (using a 3.5 inch iPhone).
What am I missing?
You need to resize the scrollview's frame, not just the content size (in fact, often you don't need to resize the content size, as the content may not change following an orientation change, but just the frame).
I had the same problem with a Popup (UIView) that was called from a (UIViewController).
In the UIViewController the popup was created as followed
func createPopup() {
let myPopup = MyPopup(frame: UIScreen.mainScreen().bounds)
self.view.addSubview(myPopup)
}
In the Popup (UIView) I needed to override layoutSubviews as follows:
override func layoutSubviews() {
super.layoutSubviews()
self.setNeedsDisplay()
let mainScreenBounds = UIScreen.mainScreen().bounds
view.frame = mainScreenBounds
super.frame = mainScreenBounds <-- Need to update the parent
** perform additional rotation/orientation code here **
}