Stop Vertical scrolling of WebView in Tableview header - ios

One of the cells in a UITableView contains a scroll view. I want to be able to scroll the content in the cell horizontally, but NOT vertically.
How can I achieve this?
Additionally, the scroll view is a subview of UIWebView, so I cannot control its content size.
I have tried setting the content offset directly, but this prevents the entire table from being scrolled. I want the table to scroll vertically, but not the content in the cell.
here is code of I stop vertical scrolling of webview in scrollview delegate-
initialisation of web-view here -
let bodyTextView: WKWebView = {
// preferences
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.dataDetectorTypes = [.all]
// webview
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.contentMode = .scaleToFill
webView.scrollView.showsVerticalScrollIndicator = false
webView.scrollView.tag = 2
webView.scrollView.delegate = self
return web
}()
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//here is code to disable vertical scrolling for webview if scroll view tag is equal to 2 set while initialising the webview.
if scrollView.tag ==2 {
DispatchQueue.main.async {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: 0)
}
}
//below code is used for Tableview-
let page = scrollView.contentOffset.x / view.frame.width
pageControl.currentPage = Int(page)
}

Related

How to Make TableView scroll inside ScrollView behave naturally

I need to do this app. The view hierarchy goes like this
UIScrollView
-UIView (Main View)
--UIView (Top View Container)
--UITableview
When scrolling up the Main View, If table view has many cells, the table view should go to the top, and once it reaches the top. The user should be able to scroll the table view cells. I was able to achieve it but it doesn't scroll naturally.
Attached my code https://github.com/iamshimak/FinchHomeScreenRedesign.git
First, never put tableview inside a scrollview, it's a bad practice. You could just use tableview header and embed any type of view do you want before the tableview cells.
here's a snipeste on how I deal with it:
//MARK: ConfigureTableView
private func configureTableView(){
let footerView = UIView()
footerView.frame.size.height = 50
footerView.backgroundColor = .white
self.tableView.tableFooterView = footerView
self.tableView.tableHeaderView = self.headerView
var newFrame = headerView.frame
newFrame.size.width = view.bounds.width
newFrame.size.height = 300
headerView.frame = newFrame
tableView.backgroundView = UIView()
tableView.backgroundView?.addSubview(backgroundTableView)
}
as you can see, I embedded a UIView as a footer and another UIView named headerView as a header
but if you insist of using a tableview inside a scrollview, you can try using a scrollview delegate and detech which scrollview is scrolling
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let yOffset = scrollView.contentOffset.y
if scrollView == self.scrollView {
if yOffset >= scrollViewContentHeight - screenHeight {
// logic when using scrollview
}
}
if scrollView == self.tableView {
if yOffset <= 0 {
// logic when using tableview scrollView
}
}
}

iOS tableview inside pageviewcontroller inside scrollview

I want to put a tableView inside a pageviewcontroller which is inside a scrollview.
So I have in my storyboard :
All constraints are respected like this
I disabled the tableview scroll but my scroll doesn't scroll, my tableView in TestVC1 not expand the PagerPlace in TestVC
How can I make my scrollview scroll and its content size depends on the tableview height + my red view?
EDIT
I tried your solution, then I got a storyboard like this :
storyboard
Then my scrollview doesn't scroll, I don't know why,
In order to make your effect perfect.
Scroll View -> UIPageViewController's view -> UITableView
Scroll View has a subview of UIPageViewController's view,
UIPageViewController has many page, one page ( a controller's view ) has a subview of UITableView
Yeah. You can change the solution.
mainScrollView ( vertical slide ) -> contentScrollView ( horizontal slide ) -> contentStackView ( has many pages) -> UITableView ( one page )
mainScrollView is UIScrollView, slides in vertical,
contentScrollView is UIScrollView, slides in horizontal
contentScrollView.isPagingEnabled = true
that simulates UIPageViewController
contentStackView has many pages, one page is your UITableView
To make it work like this:
How can I make my scrollview scroll and its content size depends on the tableview height + my red view?
for the part above the UITableView
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == mainScrollView {
// vertical
let offsetY = scrollView.contentOffset.y
if offsetY >= sillValue {
scrollView.contentOffset = CGPoint(x: 0, y: sillValue)
currentChildScrollView?.am_isCanScroll = true
scrollView.am_isCanScroll = false
} else {
let negScroll = (scrollView.am_isCanScroll == false)
if negScroll{
scrollView.contentOffset = CGPoint(x: 0, y: sillValue)
}
}
}
}
for the UITableView part
use KVO to controller the base scroll view's offset Y ,
and UITableView's offset Y is by default.
let keyValueObservation = currentChildScrollView?.observe(\.contentOffset, options: [.new, .old], changeHandler: { [weak self] (scrollView, change) in
guard let self = self, change.newValue != change.oldValue else {
return
}
self.childScrollView(didScroll: scrollView)
})
internal func childScrollView(didScroll scrollView: UIScrollView){
let scrollOffset = scrollView.am_originOffset.val
let offsetY = scrollView.contentOffset.y
if scrollView.am_isCanScroll == false {
scrollView.contentOffset = scrollOffset
}
else if offsetY <= scrollOffset.y {
scrollView.contentOffset = scrollOffset
scrollView.am_isCanScroll = false
mainScrollView.am_isCanScroll = true
}
}
the full code in github

Detect when y offset changes in scrollView with paging enabled

I would like to find out which page is visible to the user and also do a certain action when a change in the page is detected. To do this I am using the function scrollViewDidScroll. As I didn't get the result I wanted (nothing happened), I looked for answers on stackoverflow and found the following question which was answered: Detecting UIScrollView page change, to be more precise I used the answer by Michael Waterfall and converted the Objective-C code to swift code.
Below you will find the code I used to create the scrollView in my class HomeController: UIViewController, UIScrollViewDelegate {. Moreover the function by Michael Waterfall is declared and called in the function initiateScrollView(). However, the function doesn't print anything. Do you know where I am doing something wrong? I can't see where I made a mistake. Nothing happens when I scroll (e.g. from page 1 to page 2 (homeView to view2)). The function only prints before: 0 once and after that nothing happens.
Code
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
initiateScrollView()
}
func initiateScrollView() {
//create scrollView with paging enabled
let scrollView = UIScrollView(frame: view.bounds)
scrollView.isPagingEnabled = true
view.addSubview(scrollView)
//get page size
let pageSize = view.bounds.size
//individual views
let homeView = UIView()
homeView.backgroundColor = .green
let view2 = UIView()
view2.backgroundColor = .blue
let view3 = UIView()
view3.backgroundColor = .red
//array with individual views
let pagesViews = [homeView, view2, view3]
//amount of views
let numberOfPages = pagesViews.count
print(numberOfPages) //prints '3'
//add subviews (pages)
for (pageIndex, page) in pagesViews.enumerated(){
//add individual pages to scrollView
page.frame = CGRect(origin: CGPoint(x:0 , y: CGFloat(pageIndex) * pageSize.height), size: pageSize)
scrollView.addSubview(page)
}
func scrollViewDidScroll(scrollView: UIScrollView) {
var previousPage = 0
let fractionalPage: Float = Float(scrollView.contentOffset.y / pageSize.height)
let page = lround(Double(fractionalPage))
print("before:", page) //prints 'before: 0' once
if previousPage != page {
// Page has changed, do your thing!
// ...
// Finally, update previous page
print("before:", page)
previousPage = page
print("after:", page)
} //never prints anything
}
scrollViewDidScroll(scrollView: scrollView)
//define size of scrollView
scrollView.contentSize = CGSize(width: pageSize.width, height: pageSize.height * CGFloat(numberOfPages))
}
You forgot to set the viewController as the delegate for the scroll view, as following:
func initiateScrollView() {
//create scrollView with paging enabled
let scrollView = UIScrollView(frame: view.bounds)
scrollView.isPagingEnabled = true
scrollView.delegate = self
view.addSubview(scrollView)
(...) }
And I recommend that you use the scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) function, instead of scrollViewDidScroll(...)
This is because you haven't set the delegate property of your scrollview.
Add scrollView.delegate = self in your initiateScrollView method.

Scroll view with UIWebView and labels

I have a UIWebView with labels above it (see picture), but when I scroll down, the labels just stay in place and the web view scrolls down. How can I make everything scroll down in one motion ?
self.editorialDetailWebView.loadHTMLString(editorialArticleContentThroughSegue!, baseURL: nil)
self.editorialDetailWebView.sizeToFit()
self.editorialDetailScrollView.addSubview(editorialDetailWebView)
self.editorialDetailScrollView.addSubview(editorialDetailHeadlineLabel)
self.editorialDetailScrollView.addSubview(editorialDetailAuthorLabel)
self.editorialDetailScrollView.addSubview(editorialDetailPublishDateLabel)
self.editorialDetailScrollView.addSubview(editorialDetailVolumeAndIssueLabel)
let webViewHeight = self.editorialDetailWebView.scrollView.bounds.height
let webViewWidth = self.editorialDetailWebView.scrollView.bounds.width
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
editorialDetailScrollView.contentSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height * 2.0)
}
Screenshot of my issue now:
Add your views to the webview's scrollview
[self.webview.scrollView addSubview:self.myLabel];

Inserting contentView inside another view voids cell touches

I'm attempting to add a scrollview behind cell contents in a UICollectionViewCell. However, once I add it, didSelectCell... does not work anymore. Any ideas?
func build(){
scrollView = UIScrollView(frame: self.bounds)
scrollView.scrollEnabled = true
//Move the cell contents into the scrollview
self.backgroundView = scrollView
self.contentView.removeFromSuperview()
scrollView.addSubview(self.contentView)
var contentSize = self.bounds
contentSize.size.width += 100
self.scrollView.contentSize = contentSize.size
}

Resources