Can I insert a scrollview before a view in IOS? - ios

The answer can be for swift, objective-c or c# even if I'm using xamarin.
I have issues creating scrollview in the storyboard with xamarin, I followed several tutorial for xcode but I can't do what I need.
Then I removed the scrollview and just have a long vertical uiview and actualy added some code to scroll it using pangesture moving the uiview frame.
But I know it would be better to use srollview also I though that it must be possible to insert a scrollview before the view (in code) to achieve the same thing.
So is it possible ?

Yes it is possible, for example you could do this in your ViewController by adding the ScrollView as a subview to your View.
override func viewDidLoad() {
super.viewDidLoad()
let scrollViewFrame = view.bounds
let scrollView = UIScrollView(frame: scrollViewFrame)
scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
scrollView.backgroundColor = UIColor.red
view.addSubview(scrollView)
let innerView = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
innerView.backgroundColor = UIColor.blue
scrollView.addSubview(innerView)
scrollView.contentSize = CGSize(width: scrollViewFrame.width, height: scrollViewFrame.height * 2)
}
In this example the ScrollView has the same size as the main View. You can adjust this by changing the scrollViewFrame constant.
The innerView has a fixed size of 50x50. If it should cover the entire scrollView, just use the scrollViewFrame and the same autoresizingMask.
I adjusted the contentSize to be twice as high as the scrollView in order to make it scroll. This might or might not be necessary for your solution.

Related

Expanding ScrollView with TableViewCells

I am trying to expand my view when tableViewCells are added to the tableview to scroll the whole view rather than the table, but my implementation of increasing the size of the tableView and the ScrollView isn't quite working, I'm not sure if it has something to do with the code or the constraints set. What sort of constraints would I have to set in story board to make this work?
This is what I've tried and it isn't expanding the scroll view:
#IBAction func addExercisePressed(_ sender: Any) {
test.append("nice")
tableView.isScrollEnabled = false
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: self.view.frame.size.width, height: CGFloat(tableView.visibleCells.count * 120))
scrollView.contentSize = CGSize(width: self.view.frame.size.width, height: tableView.frame.size.height)
tableView.reloadData()
}
tableView.visibleCells.count isn't the same as number of cells at some time , also you need to use auto-layout constraints by giving the table in IB a default height and hooking it as an IBOutlet then inside viewDidLayoutSubviews/viewDidAppear do
self.tableHeight.constant = numOcells * 120
self.view.layoutIfNeeded()

The bottom content of the scrollView is not not responding to touch events

I have scroll view. In side scroll view I have a container view with trailing,leading,top and bottom constraints and also equal heights. I'm adding views dynamically. I'd updated the content size in
viewWillLayoutSubviews as follows.
override func viewWillLayoutSubviews() {
self.scrollView.contentSize = CGSize(width: self.contentView.frame.width, height: self.contentView.frame.height)
self.contentView.frame = CGRect(x: self.contentView.frame.minX, y: self.contentView.frame.minY, width: self.contentView.frame.width, height: 2500) // code to update the contentView's frame where 2500 is a dummy value
self.contentView.clipsToBounds = true
}
Now I can scroll until my last subview of the container view. But the problem is the last 3 subviews are not responding to the touch events.
I tried the following ways but failed.
also updated the containterView's frame
also updated the scrollview's frame
did not work.
Please help me.
func updateFrame() {
self.scrollView.contentSize = CGSize(width: self.contentView.frame.width, height: self.contentView.frame.height)
self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.frame = CGRect(x: self.contentView.frame.minX, y: self.contentView.frame.minY, width: self.contentView.frame.width, height: 2500) // code to update the contentView's frame where 2500 is a dummy value
self.contentView.clipsToBounds = true
}
try this.
I am assuming that your scrollview is bigger then Content view

Scrollview ContentSize

I am trying to make a scrollview with 3 pictures on a sign up/join page for a small app I trying to make. I was using this code below:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
var signInButton: UIButton!
var joinButton: UIButton!
var pageControl: UIPageControl!
#IBOutlet weak var scrollView: UIScrollView!
var colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor(), UIColor.greenColor(), UIColor.yellowColor()]
var frame = CGRectMake(0, 0, 0, 0)
override func viewDidLoad() {
super.viewDidLoad()
signInButton = UIButton(frame: CGRectMake(1/3.0 * self.view.bounds.size.width, 5/6.0 * self.view.bounds.size.height, 23, 60))
joinButton = UIButton(frame: CGRectMake(2/3.0 * self.view.bounds.size.width, 5/6.0 * self.view.bounds.size.height, 23, 60))
pageControl = UIPageControl(frame: CGRectMake(1/2.0 * self.view.bounds.size.width, 70/100.0 * self.view.bounds.size.height, 23, 60))
self.view.addSubview(signInButton)
self.view.addSubview(joinButton)
self.view.addSubview(pageControl)
signInButton.addTarget(self, action: "signInButtonClicked:", forControlEvents: .TouchUpInside)
joinButton.addTarget(self, action: "joinButtonClicked:", forControlEvents: .TouchUpInside)
pageControl.addTarget(self, action: Selector("changePage:"), forControlEvents: UIControlEvents.ValueChanged)
configurePageControl()
scrollView.delegate = self
for index in 0...3 {
frame.size = scrollView.frame.size
frame.origin.x = scrollView.frame.size.width * CGFloat(index)
scrollView.pagingEnabled = true
let view: UIView = UIView(frame: frame)
view.backgroundColor = colors[index]
scrollView.addSubview(view)
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height)
}
func configurePageControl() {
self.pageControl.numberOfPages = colors.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.redColor()
self.pageControl.pageIndicatorTintColor = UIColor.blackColor()
self.pageControl.currentPageIndicatorTintColor = UIColor.greenColor()
}
I put a scrollview on my view controller (using the size class width: Any and height: Any) and pinned all four sides of the scrollview to the view controller. For some reason each of the views I add to the scrollview are not exactly the same width as the iPhone.
For example when, I tried running it on an iPhone 6 the first view extends past the width of the iPhone. And that happens to the second and third view. I want the first view to be the exact width of the iPhone and the second view to be exactly to the right of the first view and so on. There seems to be some overlapping with the first view going past the width of the iPhone.
Could this be because I am using the size class (width: any and height: any) and I should disable size classes and add a scrollview for each iPhone width?
Can someone help me identify the problem here.
Add:
scrollView.setNeedsLayout()
scrollView.layoutIfNeeded()
at the beginning of the viewDidLoad() method.
Always call these two methods before accessing a view's frame when using Auto Layout, otherwise you'll probably get an incorrect size.
The problem is that when viewDidLoad() is called, your view still has a width of 600 (due to your storyboard view controller size of 600x600).
Your constraints dictate that the scroll view should be the same width as the device, but these constraints are only applied after viewDidLoad() finishes, when Auto Layout's next scheduled pass is calculated.
Adding the code above forces Auto Layout to perform a pass, thus giving you the correct frame sizes for subsequent use in your size calculations.
Put your scroll view in , set your constraint. Then grab a UIView, put it IN the scroll view, set it as equal width, equal height, and center it (use CTRL + drag to the scroll view, you'll get a small pop up menu)
Then put your content in the UIView you just created... Bam ! also I personally rename my UIView to ContentView, just for sake
Here's a screen to help :
Now I myself am still having issue with the height, I usually simply use a fixed height for the content view because if I don't it doesn't scroll....

How to embed stack view in scroll view programmatically

I have tried embedding it, but my stack view is dynamic and my app is also changing orientations time to time. I have segment control at the end of the view.
I have also tried googling it but had no luck. thanks in advance.
So far I have done:
In view did load:
mainStackView.axis = UILayoutConstraintAxis.Vertical
mainStackView.spacing = 3
scrollView.frame = self.view.bounds
scrollView.addSubview(mainStackView)
view.addSubview(scrollView)
In view did layout:
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
let top = topLayoutGuide.length
let bottom = bottomLayoutGuide.length
self.mainStackView.frame = CGRect(x: 0, y: top, width: view.frame.width, height: view.frame.height - top - bottom).insetBy(dx: 10, dy: 10)
dispatch_async(dispatch_get_main_queue())
{
self.scrollView.frame = self.view.bounds
self.scrollView.contentSize = CGSize(width: self.view.bounds.width, height: self.segmentedControl.frame.origin.y + self.segmentedControl.frame.height + 50)
}
print(scrollView.contentSize)
}
You need to set the height constraint of segment control.
For Example:
segmentedControl.heightAnchor.constraintEqualToConstant(50).active = true
More over, you can Add Empty bottom view to avoid stack view's must fill mechanism. This will show you desired view output.
var bottomView = UIView(frame: CGRectZero)
stackView.addArrangedSubview(bottomView)

Twitter-like UIScrollView with ViewControllers as pages

Video of the issue!
Example of what I mean by Twitter-like UIScrollView:
I basically have it working, but I have this small glaring issue and I don't know where it is coming from. I have checked all the constraints and values for my two view controllers, but something is off.
In short,
The code that creates the NavBar and then populates it with the two ViewControllers side by side:
override func viewDidLoad() {
super.viewDidLoad()
var navBar: UINavigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.bounds.width, 64))
navBar.barTintColor = UIColor.blackColor()
navBar.translucent = false
//Creating some shorthand for these values
var wBounds = self.view.bounds.width
var hBounds = self.view.bounds.height
// This houses all of the UIViews / content
scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.clearColor()
scrollView.frame = self.view.frame
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
scrollView.bounces = false
self.view.addSubview(scrollView)
self.scrollView.contentSize = CGSize(width: self.view.bounds.size.width * 2, height: hBounds)
//Putting a subview in the navigationbar to hold the titles and page dots
navbarView = UIView()
//Paging control is added to a subview in the uinavigationcontroller
pageControl = UIPageControl()
pageControl.frame = CGRect(x: 0, y: 35, width: 0, height: 0)
pageControl.pageIndicatorTintColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.3)
pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
pageControl.numberOfPages = 2
pageControl.currentPage = 0
self.navbarView.addSubview(pageControl)
//Titles for the nav controller (also added to a subview in the uinavigationcontroller)
//Setting size for the titles. FYI changing width will break the paging fades/movement
navTitleLabel1 = UILabel()
navTitleLabel1.frame = CGRect(x: 0, y: 8, width: wBounds, height: 20)
navTitleLabel1.textColor = UIColor.whiteColor()
navTitleLabel1.textAlignment = NSTextAlignment.Center
navTitleLabel1.text = "Title 1"
self.navbarView.addSubview(navTitleLabel1)
navTitleLabel2 = UILabel()
navTitleLabel2.alpha = 0.0
navTitleLabel2.frame = CGRect(x: 100, y: 8, width: wBounds, height: 20)
navTitleLabel2.textColor = UIColor.whiteColor()
navTitleLabel2.textAlignment = NSTextAlignment.Center
navTitleLabel2.text = "Title 2"
self.navbarView.addSubview(navTitleLabel2)
//Views for the scrolling view
//This is where the content of your views goes (or you can subclass these and add them to ScrollView)
feedViewController = storyboard?.instantiateViewControllerWithIdentifier("FeedController") as FeedViewController
view1 = feedViewController.view
addChildViewController(feedViewController)
feedViewController.didMoveToParentViewController(self)
view1.frame = CGRectMake(0, 0, wBounds, hBounds)
self.scrollView.addSubview(view1)
self.scrollView.bringSubviewToFront(view1)
//Notice the x position increases per number of views
secondViewController = storyboard?.instantiateViewControllerWithIdentifier("SecondController") as SecondViewController
view2 = secondViewController.view
addChildViewController(secondViewController)
secondViewController.didMoveToParentViewController(self)
view2.frame = CGRectMake(wBounds, 0, wBounds, hBounds)
self.scrollView.addSubview(view2)
self.scrollView.bringSubviewToFront(view2)
navBar.addSubview(navbarView)
self.view.addSubview(navBar)
}
I've looked at my storyboard and both ViewControllers seem identical in regards to their constraints.
I know this is an issue because both ViewControllers are populated by UITableViews. When I scroll through the SecondViewController, it works perfectly. When I scroll through the FeedViewController, there is a small white space at the top that I can't seem to get rid of and it shows that the text cuts off there. I've been stuck on this for a long time and if there is any other information needed, I'll gladly provide it.
Edit: Included video of the issue. If I could, I would bounty this question right now. I don't understand the cause
Update: After swapping both ViewController positions, I have noticed that the problem does not lie with either ViewController. The problem lies with page 1 being set lower. When swapped, the original SecondViewController also experienced the same behavior
So, I think everyone who implements this runs into this issue at some point. The issue isn't with the first ViewController. Simply adjust the constraint to be 44 from the top. The issue is with the second ViewController and it isn't so much an issue when you understand how they work. Technically, it is off to the side and hence its top constraint does not adhere to the Navigation Bar, so what you have is a constraint - 20. Which, depending on how you originally placed your constraints, can give you this seeming issue.
But basically, anyone and everyone will run into this issue when implementing this.
TL;DR: To make everything seamless, your second, third, fourth, fifth, etc. page View Controllers need a constraint + 20 of your first View Controller. With my set-up, I use a constraint of 44 for my first View Controller and hence 64 for the second

Resources