How to create a collection view with static cells only? [duplicate] - ios

This question already has answers here:
Is completely static UICollectionView possible?
(3 answers)
Closed 7 years ago.
I want to add a vertical collection view that contains 7 static cells. I know how to do it dynamically, but i don't see a reason to do so.
Do i have to use the cellForRow method?
I Added a collection view to my viewController, and added 4 cells, wired up the delegate from the collectionView to the vc (using storyBoard), but when i run it it shows me an empty collectionView.
I did set up the numberOfSections to return 1 and the numberOfCellsInSection to return 7. So did i miss anything? or do i have to conform to DataSource protocol and implement the cellForRow method ? (in TableView i can skip the cellForRow when using static cells).
Thanks for the help.

From the official document:
Every collection view must have a data source object. The data source
object is the content that your app displays. It could be an object
from your app’s data model, or it could be the view controller that
manages the collection view. The only requirement of the data source
is that it must be able to provide information that the collection
view needs, such as how many items there are and which views to use
when displaying those items.

Related

Working with TableViews and CollectionViews and managing multiple data sources in Swift

I have a main ViewController, MainViewController that contains a number of views along with a TableView.
Each row (i.e. tableViewCell) contains different content from different sources/views etc. A number of those rows in the tableView, in turn, contain a CollectionView called SettingsCollectionView. In the tableView's cellForRowAt method, I initialize the SettingsCollectionView for that tableViewCell and also pass it the respective data which that CollectionView subclass uses as its data source. So for example:
tableView row 0 - contains generic content
tableView row 1 - settingsCollectionViewA : SettingsCollectionView as well as a struct OriginalDataA
tableView row 2 - contains generic content
tableView row 3 - settingsCollectionViewB : SettingsCollectionView as well as a struct OriginalDataB
tableView row 4 - settingsCollectionViewC : SettingsCollectionViewas well as a struct OriginalDataC
tableView row 5 - contains generic content
When I initialize settingsCollectionViewA with OriginalDataA, I have a setter in that CollectionView that then sets up the local data under LocalDataA. This allows me to ensure I have the original and the working copy of the data based on the user making changes etc. Any time I call the OriginalDataA variable from the MainViewController, a getter in settingsCollectionViewA does some cleaning up of the data etc. so I can then do what I want with it in the MainViewController.
That part all works well except if those tableView cells are dequeued, when they reappear, I get back the original state for that tableViewCell and in turn collectionView rather than the state the user left it in.
I realize this is because each SettingsCollectionView class is working its own local copy of OriginalDataA, OriginalDataB etc. and appreciate I can just update the original data but then that creates other complexities - like the cleanness of current 'standalone' code built for the SettingsCollectionView subclass as well as the complexity of original vs. updated data. That's why I am stuck on a better programming approach...
Apologies, this might seem like a basic question but I'm new to programming and all the examples etc. I can find all speak to more simple scenarios rather than what I'm trying to do.
I haven't included the code because it's got a whole lot of other content and functionality that I think just confuses the concept outlined above.
Any help would be greatly appreciated.
Create a class that holds each of your data structs:
class MyDataModel {
var dataA: DataA
var dataB: DataB
var dataC: DataC
}
Then you create an instance of MyDataModel and hold a reference to it in a property of your view controller. Pass this same instance to your table view cells. Since it is a class and therefore a reference type, changes made by the cell will actually be made in this one instance.
Consider you have SettingsCollectionViewA which shows originalDataA. CollectionView displays the data what you provide in cellforrowatindex method. Collection view cells reuse memory every time. Only visible cells stays in the memory at any point of time. So user modified data will not be stored explicitly unless you modify the originalDataA.

Static table cells with detail

I'm trying to make an iOS 'information' or 'guide' app in Swift. I wanted to utilise the Master Detail template so that when the user clicks a cell it will take them to a relevant ViewController with either basic text labels or a PDF file.
From what I understand, Dynamic Cells can be dynamically changed whilst the app runs however I want to set static cells from the storyboard (or programmatically) and their relevant content/PDF files so the user can view each one. I don't want any "new cell" or "editing" functionality.
How can I make this work? I would post my code so far but it's almost identical to the Master Detail template so I don't see any use. I know this is quite a vague question but I need help and don't know where to start.
Any help will be so appreciated!
A static table cell can entirely be created via storyboard. In the storyboard once you add a tableviewcpntroller you can prototype call added to it.You can add as many prototype cells to your table ( not necessarily every one should have common layout). After all cells are added you can assign individual tags to the cells if you need identify these cells from your code.You can add segue from each cells to move to different page.
Let me know if something more is needed.
In Interface Builder set the Content of the table view to Static Cells.
Drag as many table view cells as you need into the table view.
In the controller create IBOutlets for the labels and the other UI elements.
Connect the outlets in Interface Builder.
Rather than using the datasource methods assign the values directly to the UI elements via the outlets.

How to have different elements in collection view? [duplicate]

This question already has answers here:
Displaying two different cells in a collection view - Swift 2.0 iOS
(2 answers)
Closed 5 years ago.
so I try to have collection view but been thinking is it possible to have different element in each cell view? For Example: in the first cell I have the whole cell covered by UIImageView while some specific cells only got UITextView.
Here's an example that I'm talking about, Medium iOS App.
Create several prototype cells, each formatted with whichever UI elements you want, and dequeue the appropriate cell for each different type of data you want to display.

How can I Change the layout of UICollectionView for both grid and list in iOS [duplicate]

This question already has answers here:
Calling setCollectionViewLayout:animated does not reload UICollectionView
(7 answers)
Closed 6 years ago.
I have a UICollectionView that is using grid layout currently I have two cells in a row.
I want to give the user a choice to switch between grid and list layout similar like table view.
How can I proceed for the same.
use segmentcontroller with uicollectionviewcontroller and uitableviewcontroller. then implement delegate methods and datasource methods for both. then hide one view controller tableview or collectionview. then implement the action for segment controller.
when segment index == 0 show collectionview else show tableview. hope this will help to you.
or else you can use same uicollectionveiw with sections.
numberOfItemsInSection shoud return 0 that means there is one item(row) per section. You consider this as list view. you can manage size or look and feel accordingly.
numberOfItemsInSection returns 2 or more whatever number of items you want in your section that means it is grid view.
You have to managa datasource methods accordingly. You should have to set some flag that keep status that user have selected the list or grid.
according to that status you can manage your datasource or delegate.
Second approach :
Use collection view for grid representation and tableview for list representation and just show and hide one of them according to user's choice as a result of grid or list.

How to distinguish 3 objects in a custom cells

I am making an iPhone app.
In this application I have to make a look like below.
I am not allowed to use collection view.
I am using tableview, and custom cells. Which I am easily able to incorporate. Means taking 3 subviews in Custom cells. And making a look.
Here the problem is In a cell, how do I distinguish each object. so that I can call each object, to set an image on image view.
Is there any Object oriented mechanism to distinguish all 3 objects in a cell ?
Try to get the data as NSArray of NSDictionary containing an array of 3 objects that you want to display on cell.
Assign tag to UImageView in the custom cell.
In cellForRowAtIndexPath, get the 3 objects and apply image using switch case.
Well everything depends on how you get the data from the server
You can use outlet collections which will give you an array of UIImageView and you can assign different tags to the imageview so you can assign to them.
You can use these guides to understand how outlet collections works:
http://nshipster.com/ibaction-iboutlet-iboutletcollection/
http://useyourloaf.com/blog/interface-builder-outlet-collections/
All the standard procedures should work to achieve this but then it only depends on how nice you want to do this.
The straight forward procedure is to expose the outlets of the image views and labels in the cell and assign the correct values to those when dequeuing/creating table view cell.
The first upgrade would be to rather expose 3 setters on the cell to simply set your model to each of them which will then internally set the images and texts inside the cell.
The next thing you may do is to rather insert an array of objects (always sending up to 3 in your case) instead of having 3 setters.
At this point you may actually rather use a collection view INSIDE the cell and make the cell a data source for the collection view. But this is totally optional.
Now since you may still dislike the table view data source you may create another model which contains an array of objects (again up to 3 in your case) and make a system that will distribute your original array of objects into the array of these containers.
If then you need to handle buttons or other touch events they may be handled with collection view delegate or 3 buttons and in both cases I advise you to handle those in the cell and create a custom delegate for the cell which will report the event with the appropriate model.
This together generates the following:
When you receive the data call a container class to distribute your array of objects (into groups of 3) and assign it to your table view data source (view controller usually)
Number of rows is the same as number of containers in the array
Cell for row assigns the container with row index to the cell. It assigns self as a delegate
Cell internally handles the object distribution either via collection view, separated outlets or outlet collections.
Cell handles actions and reports them back to the delegate (- (void)myCell:(MyCell *)cell selectedItem:(MyObject *)item;)
The cell delegate can again handle what to do upon reported actions
Also if you want to avoid a collection view inside the cell you can create a custom view using xib so you do not copy the labels, image views and such. Then simply create 3 of these custom views inside the cell. Also by using inspectable and designable these views will be visible inside the storyboard.
First I'll say that a restriction against using UICollectionView is silly. Are you still targeting ios5?
I'd look at it like this.
make your own view class for the 'subcell' let's use this term for any single instance of the 3 views per cell. I'd subclass UIImageView, adding the label for the name down the bottom and a 'setSelected:' kind of method to highlight when selected via user interaction by drawing differently.
make a UITableViewCell subclass to host and layout up to three of these subcells. I say up to 3 because the last cell may contain 1 or 2 subcells and not 3 if the total people to represent is not divisible by three.
Selection Logic: You'll need to override 'setSelected:' because you want to deselect and select only subcells, you don't want the whole cell to highlight on selection, only a third of it.
You'll also want to implement touchesEnded: in this cell so that you can figure out which of the three subcells was last touched, and you'll need to be able to query or communicate this back to the controller, probably using delegation. If the cell can communicate back whether selection was in subcell 0,1 or 2 then this together with the UITableViewDelegate didSelectAtIndexPath should map to your model nicely - selectedPerson = myArrayOfPeople[ (indexPath.row * 3) + subcellIndex ]
You'll be able to decorate your cells in cellForRowAtIndexPath: in similar fashion..
personOne = model.arrayOfPeople[indexPath.row*3]
personTwo = model.arrayOfPeople[indexPath.row*3 +1 ]
personThree = model.arrayOfPeople[indexPath.row*3 + 2 ]

Resources