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
}
Related
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
}
}
}
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)
}
I am using auto layout.
I am loading UIView from xib.
All elements have static size except UITextView.
I've disabled scroll on UITextView
UITextView is filled with the text of different size on ViewDidLoad(). So it can be 1 line or 7 lines there for example.
I am loading this UIView with the following method:
fileprivate func setTableHeaderView() {
guard let _headerView = UINib(nibName: "TableHeaderView",
bundle: nil).instantiate(withOwner: self, options: nil)[0] as? UIView else { return }
tableView.tableHeaderView = UIView(frame:
CGRect(x: 0, y: 0, width: tableView.frame.width, height: _headerView.frame.size.height))
configureViewController() // here I set the text for UITextView
tableView.tableHeaderView?.addSubview(_headerView)
}
When I load this UIView the height is always the same both before and after layoutSubviews. Actually the size always is equal to the initial size of the xib that is set in the Size Inspector of XCode.
I want to UITextView to fit the text size and to have different xib UIView size that will depend on the size of UITextView + all other elements + constraints.
I've tried different ways to implement this but but none did not help. What I've tried:
to set constraints in different ways
to call layoutSubviews() forcibly and check the size of the resulted UIView
to check size of UIView after viewDidLayoutSubviews
translatesAutoresizingMaskIntoConstraints = true with autoresizingMask = .flexibleHeight
Is it possible to implement this idea in such way?
Try to override viewDidLayoutSubviewsMethod
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Dynamic sizing for the header view
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
// If we don't have this check, viewDidLayoutSubviews() will get
// repeatedly, causing the app to hang.
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
}
}
}
I have vertical scrollView with contentSize height larger than window height. But it doesn't scroll. It even doest scroll if I set scrollView.contentSize.height = 2000
Height of scrollView is calculated on viewWillAppear when I add childviewcontroller.
code is following
self.parentView.addSubview(gameInfoMainViewController!.view)
gameInfoMainViewController!.view.frame = self.parentView.bounds
gameInfoMainViewController!.view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
gameInfoMainViewController!.view.frame.size.height = gameInfoMainViewControllerHeight!
on line where subview is added a delegate method is being called which is
func passGameInfoTeamsViewControllerHeight(height:CGFloat) {
gameInfoTeamsViewControllerHeight = height
parentView.frame.size.height = gameInfoTeamsViewControllerHeight!
parentView.layoutIfNeeded()
scrollView.contentSize.height = gameInfoTeamsViewControllerHeight! + segmentedControll!.frame.height + headerView.frame.size.height + 64
}
The most strange thing is that scroll is working if I call this code again
self.parentView.addSubview(gameInfoMainViewController!.view)
gameInfoMainViewController!.view.frame = self.parentView.bounds
gameInfoMainViewController!.view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
gameInfoMainViewController!.view.frame.size.height = gameInfoMainViewControllerHeight!
Any ideas ?
I'm trying to create a UITableView with a header view using autolayout using storyboards. It looks fine in Xcode, but when I run the app, it does not look the same.
In Xcode:
In the app:
The image has a constraint for 150x150, and there are 8-high constraints between the top-image, image-middle label, middle description-label and description label-bottom.
Both labels have numberOfRows set to 0 and lineBreakMode set to ByWordWrapping.
I have tried settings the frame via:
if let headerView = self.tableView.tableHeaderView {
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
println("Setting height to \(height)")
var headerFrame = headerView.frame
headerFrame.size.height = height
headerView.frame = headerFrame
self.tableView.tableHeaderView = headerView
}
One of the original issues was that I had some erroneous constraints (that for some reason Xcode only started complaining about today), so I have removed those and set a contentHuggingPriority of 252 (higher than all others) on the app name label. When I resize the header view manually in the storyboard the image and app name label stay the same height, and the description label grows. It would appear that the apps uses the size of the header in the storyboard at run time, and doesn't get the height from its children.
Answering my own question here:
There are 2 steps that seem to get this to work. The first is in ViewDidLoad, and the second is in viewDidLayoutSubviews:
var headerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
if let currentTableHeaderView = self.tableView.tableHeaderView {
currentTableHeaderView.removeFromSuperview()
}
// Setting the table header view with a height of 0.01 fixes a bug that adds a gap between the
// tableHeaderView (once added) and the top row. See: http://stackoverflow.com/a/18938763/657676
self.tableView.tableHeaderView = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(self.tableView.frame), 0.01))
self.headerView = AboutTableViewHeaderView(frame: CGRectZero)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let tableHeaderView = self.headerView {
var frame = CGRectZero
frame.size.width = self.tableView.bounds.size.width
frame.size.height = tableHeaderView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
if self.tableView.tableHeaderView == nil || !CGRectEqualToRect(frame, tableHeaderView.frame) {
tableHeaderView.frame = frame
tableHeaderView.layoutIfNeeded()
self.tableView.tableHeaderView = tableHeaderView
}
}
}
Hopefully that all makes sense. The viewDidLayoutSubview code is via http://osdir.com/ml/general/2014-06/msg19399.html