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
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 am trying to build this view: https://dribbble.com/shots/3812962-iPhone-X-Todo-Concept
We can see that when the user swipes up on a cell, rather than displaying a new view, the cell expands and displays more information. How can I achieve this in Swift? I use a UICollectionView to house all the cells. Thank you for your time!
So far I haven’t been able to find an answer on StackOverflow that helps with advanced animations like this. However, I think that once the cell is clicked/swiped up on, the cell expands and then a new UIViewController is presented.
There’s a handy CocoaPods library that may help you with this. You can check it out here. (https://cocoapods.org/pods/Hero)
I have a class as "myUIImage" extended from UIScrollView. it has a UIImageView variable.
ViewController delegates "UITableViewDataSource , UITableViewDelegate".
when I add a myUIImage object into all cells in cellforRowAtIndexPath function,(With a cellview that fills whole cell(frame size are same)), the problem occurs.
When i touch one of the rows didSelectRowAtIndexpath returns wrong row index on iOS7. it works well older versions.
I put the example xCode Project here ;
https://www.dropbox.com/s/ps7cc8l51v0grxb/repeatboxDeneme.zip
Thanks For Your Help...
Edit1:
Here is a sample video. Please watch carefully the Logs on down-right side.
http://www.youtube.com/watch?v=5f8-nrlWCIY&feature=youtu.be
This is working perfect on both iOS 6 and iOS7 because i've seen your code. And your code is also perfect. But there is a problem that is you are not using reusable cell. So might be it create problem releated to memory and its not a good practice.
This is no normal behaviour of UITableView. But it looks to me like it just happens if you clicked while scrolling and if it stops it remembers your last click position.
I would recommend you, to insert an UITableView into to your view inside the Storyboard. Connect the Delegate and Datasource of your UITableView with the Filesowner and than just use the methods
numberOfSectionsInTableView
numberOfRowsInSection
cellForRowAtIndexPath
didSelectRowAtIndexPath
Maybe the way you generate your tableview programmatically, there are any attributes missing. The other way you just can look at the InterfaceBuilder settings on the right and can change the settings much easier.
I was working with the grouped table view , and i wanted different controls for every row i.e switch control for 1st,radio button for 2nd ,checkbox for 3rd and so on.. how can this be implemented programmatically that is without using interface builder
thanks in advance
CharlieMezak said is right, you need to create in UIControls directly in cellForRowAtIndexPath , and add as subviews to contentView of the cell
For reference see the link below
http://www.e-string.com/content/custom-uitableviewcells-interface-builder
the link specifies the code to create cells programmatically as well as using IB.
Table View Programming Guide for iOS
Read the programing guide, and remember to use different CellIdentifier for each type of cell.
This is a pretty vague question.
Obviously you need to provide the cells to the tableview in its cellForRowAtIndexPath delegate/datasource method. So, either in that method or during the initialization of your view controller, build the UITableViewCell instances that you need, adding the various controls that you want to them as subviews and connecting the controls to your view controller so you can detect when they have been changed. Then just return the appropriate cell in the cellForRowAtIndexPath method.
Personally, I think it's a lot easier to use IB in cases like this. Just create an IBOutlet instance variable for each custom cell you want, and return the right cell in cellForRowAtIndexPath.
I have a TableView with one cell and I want to insert in this cell a lot of text so I think I'll need to use a ScrollView for scroll the text.
How can I insert? Is correct this method?
This is a help in the application, is correct use this modality?
Sorry but I'm a beginner and I don't have an iPhone or iPod, thanks!
While I concur with 7KV7's original comment, it doesn't look like there is need of a tableview in this scenario...
Just in case someone else happens upon this looking for an answer to the "Scrollview in a Tableview" question here are few clarifying points for the above comments.
The technical problem with having a tableview and a scrollview together on the same view is that UITableView is already a descendent of UIScrollView and if you attempt to handle both in the same view then you will end up with quite a mess with conflicting delegate messages.
As suggested by iPhonePgr, you can create a custom UITableViewCell. The first thought would be to let the UITableViewCell act as the delegate for it's own scroll view. The problem here is that the cell and it's contents could be discarded or reused at any moment as part of tableview's dequeue functionality.
So some ground rules to guide your implementation:
Whatever your solution, you're probably going to end up making a custom controller class, possibly derived from NSObject and implementing UIScrollViewDelegate.
The custom controller object acts as the mediator between the model object and the cell.
You will probably have an array or array-of-arrays that mirrors the model hierarchy driving the UITableView structure.
Because the cells can be discarded at any time you will have restore the scroll view state on cell initialization and preserve the state has part of handling your delegate actions or through a custom UITableViewCell implementing prepareForReuse.
Hopefully these points will come in useful to anyone who runs across this entry.
You need to create a custom cell by inheriting UITableViewCell and then add UIScrollView in the customcell. Then Use that cell in the Table view.
you can put your text in UITextView and add it as a subview in your UITableViewCell,because
UITextView is inherited from UIScrollView,
No need to add UIScrollView if you use UITextView
When you create UITableView you implement a number of delegate method which you can see by pressing the window key and then double clicking the UITableView delegate . In one of the methods you can set the cell height as per your requirement. By doing this your cell height can vary.
- (CGFloat)tableView:(UITableView *)resultTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 150;
}
As your table has a defined height, when the text in cell will be too much to contain into a scrollview will be automatically inserted.