UIView,SegmentedController & UIContainerView in a ScrollView or something similar?
In my storyboard I have a VC containing a UIView at the top, segmented controller in the middle & 2 ContainerViewControllers at the bottom with embeded segue's to new VC's.
In the new VC's I have a TableView & a CollectionView (For example, the Instagram profile).
My issue is that I need the SegmentedController and UIView to scroll with the ContainerView(TableView/CollectionView), at the moment only the ContainerView part scrolls and the parts above that are fixed.
Now I'm guessing I probably need to put everything into a UIScrollView, so I tried that & placed all the costraints correctly. But when It came to configuring it in the Swift file, I only really now how to set the height of the scroll but oviously the height I need can vary and isn't a fixed height!
If anyone can help me here that would be fantastic, or maybe point me towards a similar question already asked here? I have already looked, but did not find anything unfortunately!
Here's an image below explaining basically what I'm after, if above I wasn't very clear..
here is an example you can see: https://github.com/Jackksun/ScrollIssue
the image is here, as I dont have enough reputation I cannot place it in the post!
You can use only UITableViewController. You will define three custom cells and in cellForRowAtIndexPath ask for the Index number, if it is 0 you will set the elements in that cell accordingly
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: TableViewCell!
// stuff in UIView
if indexPath.row == 0 { set the cell here}
// for UISegmentedController
if indexPath.row == 1 { set the cell here}
// cells that will repeat
if indexPath.row >= 2 { set the cell here}
return cell
}
Update1
Define how many custom cells you will use in Attribute inspector for tableView, you will see them instantly in Storyboard
Update 3
Did you mean this? It is completely table view with 4 custom cells. I didnt use Collection view at all but I think it works as you wanted
Related
Hi guys, please give me an idea how to create a list similar to the homepage of iflix (image attached below). I tried using table view with collection view inside the cell, but I don't like the performance because it flickers when I scroll because of the reloading of collection view cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CustomCell = self.tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
cell.bind(data: self.datas[indexPath.row])
cell.collectionView.reloadData()
cell.delegate = self
return cell
}
When I removed the cell.collectionView.reloadData() the scrolling is smooth but the displaying of data is incorrect because cells are reusing.
Can anyone give me a better idea on how to implement a layout like this? Thank you in advance.
there could be a variety of reasons why you are experiencing flickering, in fact the first release of that ViewController had the same issue on older devices. I would recommend first Analysing your app using the Time profiler to investigate the cause of the flickering you are experiencing. It’s very likely, as we discovered there there is not one main cause but a collection of smaller issues that when added together on the main thread causes the flickering. Below I will detail a brief description of how we manage to reduce the flickering effect.
The ViewController contains one vertical collection view, each row is its own cell that owns a horizontal collection view.
One thing we try to ensure is that drawing a cell is as efficient as possible. All cells and views are configured via ViewModels which for our case is a PODO (property only data object).
The ViewModels can be easily preprocessed on a background thread and contain e.g url, titles, hide/show buttons, cell sizes etc for any orientation. Plus it makes it very easy to test. We ensure that all images are the correct size so there is no time required to scale the image, along with that each visual item is opaque and rasterised to the correct screen scale. We also found for our code that if each cell uses ‘preferredLayoutAttributesFitting’ that can help to reduce the flicker also.
The next part is to try to help reduce the amount of effort taken to when calling reloadData. If each cell in the row is the same size then using UICollectionViewDataSource can be more process intensive than setting the item size, instead you can set the itemSize in the xib/storybaord or use a UICollectionViewFlowLayout. Before a cell is shown to the user the methods “collectionView cellForItemAt” and “collectionView willDisplay” will be called, you can try and split cell configuration work over those two method calls.
I hope that helps.
I will try to explain my problem with the help of pictures :
Firstly, I just added an UITableView to my UIViewController. I selected it to show its frame and there was no problem.
Next, when I connect my button to my UIViewController, my UITableView gets smaller.
I selected it to see that the frame doesn't match with the contents. I noticed that the tableview reduces exactly of 64 (44 from the UINavigationBar + 20 from the bar with the battery)
At the beginning, I thought it was juste a display problem from XCode, but next when I tried to run it with cells, the problem still exist.
So I put a UIContainerView in my UIViewController and my tableView in the controller of the container. XCode display properly my table view, but when in run it, I get the same problem.
Thank you in advance,
Sorry for my english.
The problem is that your containing view controller's Adjust Scroll View Insets is checked (in its Attributes inspector). Uncheck it.
You can use this function to explicitly set the size of your cell.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
}
Description:
I have a list of UITableViewCells that have each have a UICollectionView with X amount of UICollectionViewCells (see image below for more clarity)
The idea behind this is to be able to implement sections with a header on top and a horizontal scrolling UICollectionView
Everything is working great, except when I try to focus the UICollectionViewCells (aka: CategoryCell). The UITableViewCell gets focused and highlights all the content making it impossible to focus any of the UICollectionViewCells.
What I've tried:
According to other posts the fix for this would be deactivate User Interaction and/or set the selection style to none on the UITableViewCell:
cell.selectionStyle = UITableViewCellSelectionStyle.None
and to enable User Interaction on the UICollectionViewCell instead.
Here are posts that talk about it:
UITableViewCell with UITextField losing the ability to select UITableView row?
How can I disable the UITableView selection highlighting?
I've attempted to implemen these solutions without success.
Question:
What step did I miss? Does the fix not work on tvOS? How do I focus my UICollectionViewCell that is in a UICollectionView that is in a UITableViewCell?
More:
Image showing my UITableViewController and all it's contents from my StoryBoard.
The problem is most likely that your table view cells are returning true to canBecomeFocused. You can disable that by either implementing the UITableViewDelegate method tableView(_, canFocusRowAt:) to return false, or by subclassing UITableViewCell and returning false from canBecomeFocused.
The focus engine will try to focus on the top-most view that returns true from canBecomeFocused, which is why it can't find your collection view cells: they're "hidden" inside the focusable table view cells. If you disable focus on the table view cells, then the focus engine will be able to find your collection view cells.
override func tableView(tableView: UITableView, canFocusRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
I have a uiviewcontroller that contains a uitableview, this uitableview is full of custom cells that contain a textfield.
This view in storyboard is loaded as a popover, so the behaviour is:
iPad - If the keyboard is loaded and the keyboard hides the current editing cell, the cell automatically moves up so it is visible, regardless of its position in the tableview
iPhone - It doesn't, the tableview dosn't move if the keyboard hides the cell.
Can anyone suggest an elegant way round this?
Thanks
I had similar issue using Xcode 8.2.1, swift 3 with keyboard hiding UITextView when it becomeFirstResponder(), spent few hours to figure out what was the problem without any luck, finally created new test project with single UITableViewController and it worked, thereafter re-created the Table View Controller in storyboard - cells started to scroll to allow space for keyboard which appears just below the designated text view as expected...
perhaps something with wiring that prevented it from working properly
You can use the table view method scrollToRowAtIndexPath
func scrollToRowAtIndexPath(_ indexPath: NSIndexPath,
atScrollPosition scrollPosition: UITableViewScrollPosition,
animated animated: Bool)
to scroll the table view when a text field becomes the first responder, for example:
let indexPath = NSIndexPath(forItem: 4, inSection: 0)
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
See the UITableView reference for further information
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/doc/uid/TP40006943-CH3-SW44
I hope this helps you. Feel free to ask if anything is unclear.
so I am exploring the new tvOS. As I wanted to kind of replicate the horizontal feature section of the app store (e.g. "Best New Apps")
My plan was to use a UITableView to lay out the base structure (rows) and use an UICollectionView for all the individual horizontally scrollable items.
Unfortunately the tvOS always focuses the UITableViewCell, not the UICollectionViewCell inside. I've already read about the
override var preferredFocusedView: UIView? {
return aView
}
So using this inside my controller is kind of hard regarding getting the correct subview.
Is there anything I could look into or could someone please point me in the right direction? Iterating through all subviews until I get the correct one seems like a bad idea.
Thanks a lot!
I tried out a similar situation where I had a CollectionView within a CollectionView to get the setup you described. Let's call them innerCV and outerCV. To get innerCV to be focused and not outerCV's cells, I set this delegate method to return false for outerCV.
- (BOOL)collectionView:(UICollectionView *)collectionView canFocusItemAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
In turn, innerCV's cells are now focusable as opposed to outerCV's cells.
Credit for this goes to Apple. I used their sample project as a guide to start. Check out the Focus samples within their project.
Sample Project: Apple tvOS UIKitCatalog
I used a different approach..
Setting the tableview selection property to No Selection in storyboard makes the focus engine to focus on UICollectionViewCell cell rather than UITableViewCell.
Hope it helps :)
Image