How to assign a specific ViewController to a UIView (in UICollectionView)? - ios

I searched the web for hours but I can't find a solution to my problem.
I have a View in my storyboard that contains a UICollectionView. I've set the cells of the UICollectionView to be really big (only one can appear on the screen, you have to swipe horizontally to see the others). In my application, I use this layout to ask the user some questions, one after another. The user can respond to those questions by touching buttons, move around a map, select a date, etc... Each questions have the same layout; they are displayed in a box, with a title label and a button. That's why I chose to use a UICollection View.
I want to display a specific view (the options that allows the user to answer (buttons, Map, DatePicker, etc..)) for each questions in the blue rectangle (see picture below).
A screenshot of my view
My idea was to create multiple ViewControllers in my StoryBoard and be able to tell : "ok, for the first question (first cell), put the view XXX in the container, for the second, put the view YYY, etc...".
How can I do this ?
I've tried to add a ContainerView but we can only link one view in the storyboard.
I want to able to do something like this :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! SearchQuestionBox
cell.questionAnswersZone.view = storyboard.viewNumberOne //Just for the idea haha
return cell
}

I would suggest not using multiple view controllers.
Instead you could just add the views for each cell to the one main view controller. Keep in mind you can set a views frame to be offscreen.

Related

How to switch to another screen by clicking on a custom image that is inside a table cell?

I don't have enough skills in iOS development that's why I need your help. Could you please to describe me how can i switch to another screen by clicking on a custom image that is inside a table cell? I am building an application based on MVC architecture, all my part of codes are divided to different files. I have a table which contains a certain number of cells. Each cell has a View and inside its content. One of the contents is a small picture when it clicked it should move to another screen. How can I realize it? I am so sorry I can't share you the parts of codes. Cause it is commercial project. I want to know the implementation principles in this case. I don't use (No - Storyboard), making an app only programmatically. I would be very grateful to you for your help.
There are 2 ways of handling it
Custom Cell:
Custom Cell will have the action handler
Delegates the call to Table View Controller with meta data
Present another screen from Table View Controller
Table View Delegate Method
optional func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath)
Based on the index check we can read the data from the datasource
Present new screen from the table view controller
Try this
var body: some View {
Link("Show example", destination: URL(string: "https://www.example.com")!) // 1
}
}

Is it language appropriate to layer a UIButton over a UILabel in Swift 3.0?

My question is this: Is this following approach to making a UILabel tap sensitive stylistically acceptable in the Swift 3 language? I'm tempted to say "if it compiles it flies" but I don't want to get in the habit of using this "short cut" if it is going to bite me later on. Further, if it is acceptable, are there some drawbacks to using this method that aren't obvious to a newcomer like me?
Please note that I am not looking for a way to implement code, I have one. I am asking if the solution I have is acceptable from a language style perspective.
I've been trying to get a UILabel to accept a TapGesture when inside a table cell for 2 days now and whatever method I try, there is always some sort of error even if it will compile. On a hunch, I went to my storyboard for the table view and added a button on top (not stacked, or aligned, or anything like that – actually occupying the same 2D space on the story board) within the prototype cell. I deleted the button text, linked it to the table view cell code and implemented some basic functionality to change the text on the UILabel to red and back. All of this functions exactly like I expected. I click the button and the text changes from black to red, and back when clicked again. The UILabel text is static in the table cell on a white background and my real function isn't going to change the text, it is going to alter another view through delegation from that view.
Why do it this way? Even if I check the UILabel use interaction box and follow some of the other questions and answers here to make it tap-able, I cannot control+drag the UILabel to the table view cell and make an action, the option simply doesn't exist in the pull down menu. It is available if I control+drag the UILabel to the table view controller. This makes a kind of sense to me because it is the table view controller that senses touch (right?). But, on the other hand, I have a switch in the table view cell that works just fine when I follow the answer to this question. Simple functionality of the storyboard-code interation (control+drag) is preventing me from getting what I want. Maybe control+drag should be allowing me to make an action and doesn't? I don't know. I don't want to use a UIButton alone because the text scaling feature of UILabel is really handy.
If you just want to recognize taps on the table cell, make the class the delegate of the table view
tableView.delegate = self
and implement
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//your code here
}
I'd also appreciate you taking the time to read a bit more about UITableViews. Every UITableViewCell has a label by itself. Consider the following code:
tableView.dataSource = self // this code will ideally be in init
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "lovCell")
cell.textLabel?.text = dummyData[indexPath.row]
return cell
}

UICollectionView, button not appearing

I am still fairly new to programming and I do not quite understand UICollectionViews. Can a programmer add buttons in the cells of an UICollectionView? Or only UIImages? I added a button into one of the cells and when I ran the iOS simulator nothing appeared. I also just dragged in an UICollectionView and I am not using an UICollectionView view controller. I dragged the UICollectionView into code as an outlet too and constrained the view, cell and button. Attached is a screenshot of my view controller and iOS simulator. Thanks!!
I was recently new to collection views, and they can be confusing. I found a video tutorial that explains it all really well, but it was not updated for Swift 3 so I wrote made this GitHub project to help explain it to new users.
You can certainly add buttons to to the cells of a UICollectionView. Each cell is like a little UIView in and of itself. However, I believe you need to create a new class for the cell and create an IBOutlet for the button. You also need to create a couple of functions inside your main ViewController.swift file to actually view the UICollectionView. It can be complicated at first, but stick it out! In a little while, you'll be able to do them with ease. Follow the tutorial in a new project to practice, then you might figure out what the problem is.
Sorry that that last one was unhelpful, I'm new to this. Thanks for the tip, manetsus!
I created a new project and tried to add a button to the UICollectionViewCell. Here's what I did:
I added a button to the cell, then created an IBAction by control+dragging from the button to ViewController.swift. I ran it, and it worked. Each button within the UICollectionView cells performs the IBAction in ViewController.swift.
If you want cell-specific actions, consider using:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
//Do something with the cell...
}

iOS Table cell styling

In my iOS - swift project I need my table cells to look like this. I can get the multi select option by making the table editable. What I need to know is what are the ways that I can design a cell to look like this? How can I add that colored border at the bottom and how can seperate the cells to look like this?
Thanks
The cells you show in your question are custom cells. To make that, you would need to design those cells yourself with views, labels, buttons, etc. There is no default/boilerplate code that can do this for you; you will need to implement it yourself.
You must create and implement this custom cell.
Create a New file, Cocoa Touch class, on next page select "subclass of: UITableViewCell" and name "CustomCell"
Create a New file, select User Interface (under iOS) and select Storyboard, and Name something like "MyCustomCell". On this new storyboard drag a Table View Cell. Select this cell, and in identity inspector make the class = to the name of your "CustomCell" cocoa touch class file. Then go to Attributes Inspector and fill in "identifier" with "cell"
NOW
In your TableViewController file
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: CustomCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! CustomCell
// Here's where you set your CustomCell properties like label title, images, backgrounds
return cell;
}
I don't know yet how to make the cells separated, but as to the border at the bottom just go to your "MyCustomCell" xib and add a view at bottom and change its background.
Maybe to get the space in-between you can use some sort of Layer (CAlayer).

Can you store state in a custom UICollectionViewCell? Or can the state get erased (like when the cell scrolls off the screen)?

If I create a UICollectionViewCell subclass like:
class StudentCell: UICollectionViewCell {
var student: Student?
}
And in my controller I implement UICollectionView's didSelectItemAtIndexPath and set the variable:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if let studentCell = collectionView.cellForItemAtIndexPath(indexPath) as? StudentCell {
studentCell.student = self.someStudent
}
}
When I click on the cell it should set student, but if the cell is scrolled off screen it seems like the whole cell might get wiped and when it comes back on screen it would need to rebuild itself in cellForItemAtIndexPath.
The problem I have is that I have a UICollectionView with cells that do not scroll off the screen that I'm storing data in. Because they don't leave the screen I assume they should not get wiped, but one of the cells does not seem to keep it's variable, which makes me think maybe it's getting wiped and I may need to move the state outside of the cells to a dictionary or something and in didSelectItemAtIndexPath instead of setting the variable in the cell I'd set the dictionary. Whenever I need to access the data instead of asking the cell for it I'd look it up in the dictionary.
But either way, I was wondering if it's possible (or a bad idea) to set it in the cell or not.
Yes, cells in both UICollectionView and UITableView can (will) be reused at the systems discretion and should not be used to store state information, only display information. Specifically, both views will reuse cells when they are scrolled off-screen, but there's no guarantee this is the only time they'll be reused. The usual way to handle this is to define some kind of cell data object which stores the data for each cell (visible and not) and refresh the cell view from that as needed/requested.
Tables display their data in cells. A cell is related to a row but it’s not exactly the same. A cell is a view that shows a row of data that happens to be visible at that moment. If your table can show 10 rows at a time on the screen, then it only has10 cells, even though there may be hundreds of rows with actual data. Whenever a row scrolls off the screen and becomes invisible, its cell will be re-used for a new row that scrolls into the screen.

Resources