I have a UICollectionViewCell which I created using a visual XIB file.
The collection view is horizontally displayed.
I'm wanting to add another UICollectionView to this cell in the footer of the cell.
The cell itself is a "card" representing some information;
This diagram helps illustrate what I'm after;
The idea is that I can show/hide the dice imagery as many as needed, including zero; in a horizontal fashion as a child partial inside the current UICollectionCell.
Attempts using Storyboards;
The collection cell XIB won't let me add another UICollectionView to it
If I make a standalone UICollectionView inside the same storyboard, it won't let me add a UICollectionCell to it
The only solution I've got so far is to manually create 5 imageviews, then attach them to a collection outlet; and then I would need to do a for-loop to show/hide each die imagery.
Create normal View Controller with Collection View in the interface builder
Create CollectionViewCell in separate XIB. Inside this cell insert another CollectionView
In first VC register that collectionViewCell as sectionHeader:
tableView.register(UINib(nibName: DashboardPagerHeader.cellIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: DashboardPagerHeader.cellIdentifier)
Create another CollectionViewCell in separate xib like before
Inside class of first collection view cell in awakeFromNib register cell created in step 4 like that:
override func awakeFromNib() {
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UINib(nibName: " DashboardHeaderCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: DashboardHeaderCollectionViewCell.cellIdentifier)
}
You don't need tableview for that just in your collectionview cell xib drag another collection and set its scrolling property to vertical,then create xib from inner collectionview.
In outer collectionview cell use that method to set delegate and datasource
// code
override func awakeFromNib() {
super.awakeFromNib()
serInnerCollectionView()
}
func serInnerCollectionView() {
collectionViewInner.delegate = self
collectionViewInner.dataSource = self
collectionViewInner.register(UINib(nibName: " FooterCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "FooterCollectionViewCellIdentifier")
}
Related
In a normal storyboard, table views come "with" embedded cells. Simply set "Dynamic Prototypes" to 1 (or more):
You then use the those cells in your view controller simply with
...cellForRowAt
let cell = tableView.dequeueReusableCell(
withIdentifier:"YourCellClassID", for: indexPath) as! YourCellClass
Where YourCellClass is the class of the table view cell,
and the string "YourCellClassID" is just
the "Identifier" set in the Attributes Inspector (nowadays the **5th button)** of the storyboard.
(Be careful to NOT use the "restoration identifier" on the 4th button, identity inspector, which sounds the same but is unrelated.)
But what if you want to use an XIB file?
Instead of using one of the prototypes "in" the table view in storyboard?
If you use an XIB file, you can use the same cell in different tables.
How to do it?
Step 1, to make a cell-style XIB file
In current (2020) Xcode there's no direct button to create a table view cell -style XIB file.
The secret is
create a 'Cocoa Touch Class', select UITableViewCell
and ALSO select 'create XIB file'
You now have a cell-style XIB file, TesteCell.xib in the example.
(Feel free to delete TesteCell.swift if you don't need it.)
Step 2, add the register#UINib code in viewDidLoad
If you now try this:
let cell = tableView.dequeueReusableCell(
withIdentifier: "TesteCellID",
for: indexPath) as! TesteCell
In fact it does not work.
In viewDidLoad, you must add
override func viewDidLoad() {
super.viewDidLoad()
// We will be using an XIB file, rather than
// just a cell "in" the table view on storyboard
tableView.register(
UINib(nibName: "filename without suffix", bundle: nil),
forCellReuseIdentifier: "identifier in attributes inspector"
)
}
In the example
override func viewDidLoad() {
super.viewDidLoad()
// We will be using an XIB file...
tableView.register(
UINib(nibName: "TesteCell", bundle: nil),
forCellReuseIdentifier: "TesteCellID")
}
And that's how you do it.
Summary
New file - cocoa touch class - subclass of table cell - do select 'also create XIB file'
In viewDidLoaed, register the XIB file using,
The file name (no suffix) and the identifier
You're done, you can now refer to the cell in the normal way in dequeueReusableCell
I have a xib that is a UIView, with class MyUIView. I'd like to re-use this view as a Table View Cell, but I'm not sure how I would do that.
I know I have to register the xib for my table view, like:
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "MyUIView", bundle: nil), forCellReuseIdentifier: "MyUIView")
}
But other than that, I'm not not sure how to upcast it to a Table View Cell. What modifications do I need to make to the regular Table View/Table View Cell process to use my UIView xib as the cell?
Add a UIView control to your table view cell. Then set its class to MyUIView.
I have a childViewController on a UICollectionViewController. I have so my childViewController appears on the screen. But when I register a cell collectionView?.register(MyCustomCell.self, forCellWithReuseIdentifier: CellId) and use numberOfItemsInSection and cellForItemAt. The problem is that the cells wont appear, I have checked the code so it´s right. Can it be something with the childViewController?
Generally it's not preferred to add any child view or viewController to UICollectionViewController or UITableViewController as you will see un-expected results as both of them inherits from scrollview and make the added content scroll able or scattered any place, if you have then better create a custom viewController with a collectionView and the childViewController
I have a Custom UIView with an XIB. This custom UIView has a UICollectionView which is connected to an IBOutlet. In the view setup, the UICollectionView is initialised properly and is not nil.
However in the cellForItemAtIndexPath method, I get this error:-
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key selectorCollectionView.'
If I remove the datasource and delegate, I do not get any error. If I add them Iget an error at this line:-
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "selectorCell", for: indexPath) as! SelectorCell
Please help!
Edit: I have attached screenshots of my setup
I have uploaded the project here too http://www.fast-files.com/getfile.aspx?file=148623
Maybe a sync issue. Happens sometimes:
Try cut outlets loose and reconnect them.
Make sure Collection Reusable View identifier is defined in xib file:
Make sure collection-view cell's custom class is define in xib file:
EDIT:
I dug into your project and here are my findings
UICollectionView should be init' in awakeFromNib method (override it):
override func awakeFromNib() {
super.awakeFromNib()
let cellNib = UINib(nibName: String(describing: "SelectorCell"), bundle: nil)
selectorCollectionView.register(cellNib, forCellWithReuseIdentifier: "selectorCell")
selectorCollectionView.dataSource = self
selectorCollectionView.delegate = self
}
loadViewFromNib should be looking like this (Remove collection view init'):
func loadViewFromNib() -> UIView {
let nib = UINib(nibName: "SelectorView", bundle: nil)
let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
return view
}
Subclass SelectorTableViewCell likewise.
class SelectorTableViewCell: UITableViewCell {
#IBOutlet weak var selectorView: SelectorView!
}
In Main.storyboard - custom class UITableViewCell to SelectorTableViewCell and connect SelectorView inside contentView to 'SelectorTableViewCell''s outlet.
That's it i think. Here is the project:
You can try the following:
Click on File Owner at the left panel of YourCell.xib. Then go to Attributes inspector and check whether there is any class specified in Class field. If not - no help from me here. If yes - remove it and tap Enter.
In YourCell.xib sequentially click on all subviews and delete all the outlets in Connections Inspector. No need to delete them in YourCell.swift.
Once your cell's File Owner and outlets are removed, we're ready to reconnect the outlets. Just drag every one as usually to an existing corresponding IBOutlet in YourCell.swift.
As a result, when you click on YourCell at the left panel of YourCell.xib and go to Connections Inspector, you'll see there are all the outlets connected. Like so:
And if you check connections for a particular view in YourCell, you should see that it's outlet is connected to YourCell (StaticSlot in my case).
This helped me and hope you'll get the same.
In our case, the problem was making the wrong connection in Storyboard. Click on the custom class in Storyboard -- not the File Owner -- then connect the IB outlet to the variable in the custom class.
if try to register you custom class and cell ID
self.collectionView.register(nib, forCellWithReuseIdentifier: "Cell")
self.collectionView.register(CustomClassCell.self, forCellWithReuseIdentifier: "Cell")
My interface consists of two things inside my main ViewController: a label (the top half of the screen), and a table (the bottom half).
For the life of me, I cannot find a tutorial or example in Swift 3 + iOS 10 where a UITableView is successfully used, as opposed to a UITableViewController which takes up the entire screen.
What must be done to use a UITableView with dynamic cells in the bottom half of your interface?
I tried adding the UITableView, then creating a subclass of UITableViewController, but I was unable to select this in the UITableView's Custom Class -> Class dropdown. Apparently, I need to subclass UITableView, but I can find no examples of how to do this.
Use a standard UIViewController and drag a table view into the canvas.
In IB connect the table view to the IBOutlet and delegate and datasource to the controller.
class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView : UITableView!
...
Unlike UITableViewController you have to implement all relevant datasource and delegate methods.
At first , the UITableView and UITableViewController are not the same thing, the TableView is a view and TableViewController is a Controller withe a tableview inside.
If you are using UITableViewController you should drag a UITableViewController, and then change its class in the third tab on the top!
If you are using a basic ViewController and drag a TableView inside, you could get The TableView in the ViewController using an IBOutlet.#John D.
You can use normal ViewController and init a UITableView in the viewDidLoad and add it to the ViewController.
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView = UITableView.init(frame: CGRect(x:0, y: 300, height: 300, width:screenWidth))
self.view.addSubview(tableView)
self.tableView.register(UINib.init(nibName: "NameListTableViewCell", bundle: Bundle.main), forCellReuseIdentifier: nameListTableViewCellId)
// Do any additional setup after loading the view.
}
set the tableview.delegate = self and tableview.datasource = self,
using methods in the pic and lots other in the UITableViewDelegate and UITabelViewDataSource protocol to Custom your tableView!
hope this would help