Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have a UICollectionView which displays content received from the web. The number of cells can be known only at runtime. Client's requirement is that each row in the collection view must have a different color.
For example, If I have to show 12 items in my UICollectionView then suppose if first row has 3 cells then the colour of all three cells should be red.
Cells of second row should be white and so on.
Could you please help me how to achieve it?
Thanks in advance.
on cellForRowAt, if you want to intercalate colors, you can check indexPath.row and update the background color.
if indexPath.item % 2 == 0 {
<#YourCell#>.backgroundColor = .blue
} else {
<#YourCell#>.backgroundColor = .green
}
Also, if you want random colors, you can check this answer: How to make a random color with Swift
Then you just set <#YourCell#>.backgroundColor the random color
In the case that the collectionViewCell has another collectionView on each cell, and those have to match the same color for each parent collectionView row, I'd suggest you to create a custom class for the parent collectionView cell, so that every collectionView child row can consume from it and set it's own backgroundColor.
Updated answer:
I'm supposing you have initially you have these variables like:
private let cellBackgroundColors: [UIColor] = [.yellow, .green, .blue, .purple]
private let numberOfRows = 3 (or you can assign it dynamically)
Second step, implement like this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ToDoListCollectionCell
let index = indexPath.item / numberOfRows
if index < cellBackgroundColors.count {
cell.backgroundColor = cellBackgroundColors[index]
} else {
cell.backgroundColor = .white // Set your default color to handle this case
}
return cell
}
Happy Coding !!
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
I was implementing multiple sliders in a page in ios 14.2. The UI had a tableview and 4 cells. Each cells had a slider. It was working fine in 14.2. But when I updated my iPhone os to 16.3.1, the sliders are not behaving properly.
When I try to move the first slider, the first and fourth slider is moving at the same time. And when second slider is moved, second and third sliders are getting moved. Have anyone encountered with this issue before.
You might be reloading/updating you tableView when slider changes. Do not reload table view.
Create a Model class for you cell
class MyModel {
var title:String?
var sliderValue:CGFloat
}
Pass the model to cell and update you model directly
class MyCustomCell:UITableViewCell{
var model:MyModel!
func configure(item:MyModel) {
self.model = item
}
#IBAction func sliderChanges(_ sender: UiSlider) {
self.model.sliderValue = sender.value
}
}
And finally pass the change your cell for indexPath method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for:indexPath) as? MyCustomCell
cell.configure(item:self.items[indexPath.row])
return cell
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How to handle drag and drop between two collection-view cell. we also have cell reorder functionality(implemented).
What exactly we need is: drag cell's subview (UILabel) and drop it to another cell
You can try the following:
Add long press gesture to cell label.
On tap begin you hide the source label and create a snapshot of the label.
then drag it to the destination cell, get the index path from the location of the touchpoints.
On ending the gesture, add the label text to the destination cell label, and remove the snapshot.
I think this will work. I had not tried this before, but I think this will work.
Step 1 : First You need to set drag and drop delegate like as below
collectionView1.dragDelegate = self
collectionView2.dropDelegate = self
Step 2 : You need to add which item to drag in itemsForBeginning delegate method
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem]
{
let item = imageArray[indexPath.row]
let itemProvider = NSItemProvider(object: item as NSString) //Here For your use case you can add label for drag
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
Step 3 : You need to add performDropWith delegate method to drop item for collectionView2
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)
{
let destinationIndexPath : IndexPath
if let indexPath = coordinator.destinationIndexPath
{
destinationIndexPath = indexPath
}
else
{
let row = collectionView.numberOfItems(inSection: 0)
destinationIndexPath = IndexPath(item: row - 1, section: 0)
}
if coordinator.proposal.operation == .copy
{
//Here you can add your copy code
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
i have a UITableViewController configured with a static table made up of 5 custom cells (this is meant to be a form).
cell 0 captures a date
cell 1 is a UICollectionView filled with icons representing activities. depending on which activity is selected, one of many custom UITableViewCell are loaded on the fly in cell 2 .
cell 2 can be simple (just a slider), a textfield or more complex (a UITableView)
cell 3 has a textfield to capture a description.
cell 4 is for additional notes
so far everything is working as expected. I select an activity in cell 1, the matching XIB is loaded in cell 2, data is captured, comment added etc and form is saved. Where i am challenged is in the case where based on the the input in cell 2, i would like to update cell 3 automatically. i got it working but i feel it isn't elegant or clean so would appreciate others input. in
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// main table cells pseudo code
switch indexPath.row {
case 0:
<#code#>
case 1:
// dequeue collectionviewcell
case 2:
// dequeue the relevant uitableviewcell based on selected cell in the uicollectionview
switch selectedIndexPath.row {
case 2:
<#code#>
default:
<#code#>
}
case 3:
// handle the description field
default:
<#code#>
}
a specific activity will load "eventFlushMedTableViewCell" which is meant to display a list of meds in a uitableview. based on which meds I select, i would like to take the name of the meds and put them in cell 3.
case 2:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventFlushMedTableViewCell", for: indexPath) as! eventFlushMedTableViewCell
// fill the meds table with the list of Rx meds
cell.medsArray = medListArray.filter { $0.medRx == 1}.map {return $0.medName}
// return the selected values from the table
cell.returnValue = { selectedIndexPaths in
let indexList = selectedIndexPaths.map { $0.row }
self.selectedMedsName = indexList.map {cell.medsArray[$0]}
// force a reload of cell 3
let myIndexPath = IndexPath.init(row: 3, section: 0)
tableView.reloadRows(at: [myIndexPath], with: .none)
}
return cell
and cell 3 in the main table is dequeued and configured
case 3:
let cell = tableView.dequeueReusableCell(withIdentifier: "eventDescriptionCell", for: indexPath) as! eventDescriptionCell
if !selectedMedsName.isEmpty {
cell.eventDescriptionTextField.text = selectedMedsName.joined(separator: ", ")
}
something tells me the closure around (cell.returnValue {...}) in case 2:, even though it is working, isn't the right way of doing this... any advice ?
thanks
I think a good way of approaching this would be to create a custom delegate.
Let's name it ActivityCellDelegate. You can create it like this:
protocol ActivityCellDelegate: class {
func activitySelected(_ activity: Activity)
}
We use 'class' so we can make the delegate 'weak' reference. Otherwise XCode will cause trouble :).
Using an enum to represent different activities is a nice touch. You could also use a String as an identifier or an Int as an id.
enum Activity {
case activity1
case activity2
...
}
Add a delegate property to the TableViewCell:
weak var cellDelegate: ActivityCellDelegate?
Then, when dequeuing a cell, you set it's delegate to self cell.cellDelegate = self, and make the controller that has tableView as a subview conform to the delegate protocol.
extension TableViewController: ActivityCellDelegate {
func activitySelected(_ activity: Activity) {
//...in here you would probably reload the third cell in the table view. You could add an additional property in the ViewController in order to know which activity is currently selected.
}
}
In the end, when user selects a CollectionViewCell to choose an activity in collectionView:didSelectItemAtIndexPath: you should call the delegate method:
delegate?.activitySelected(.activity1)
I am attempting to setup and write a question and its corresponding answers to a table view with each cell representing one of the answers from a dictionary and a question.
The dictionary is setup as follows:
struct Quest {
question: String,
ans1: String,
ans2: String,
ans3: String,
ans4: String,
cor: String
}
The struct can hold anywhere from 1 questions [0] through [100]
I was attempting to call the reloadata() function but that loads up a different question in each cell, whereas I need to load the question first and then the four answers. Just not sure how to accomplish this.
Here is my cellFor code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
let label1 = cell.viewWithTag(1) as? UILabel
let myView = cell.viewWithTag(3)
let myItem = items[indexPath.row]
print(indexPath.row)
label1?.text = "Question"
return cell
I tried having it return the cell and then added the code below that to load the next one but it keeps telling me that once I return the rest of the code won't execute, which I understand.
Any help would be appreciated.
It sounds like you need a sectioned table view, with each section containing the question in the section header in the cells in that section containing the answers.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'd like to find out all UITableViewCells (number varies) which have an detailTextLabel with the text "Done" in it. How can I do this in Swift?
You should not do this. Neither in Swift nor in any other language. You should query the dataSource because that is where the true state is stored. If you scroll a cell offscreen it get's reused, and the text gets set to something else. You can't rely on that information. Even worse, if you rely on texts in your cell you never get the whole picture about your dataSource, because the cells that are offscreen simply don't exist.
Here's what you should do: Somewhere in your code you set the text to "Done" depending on the state of an object. Use the same decision to find all objects that are done.
For example, if your object has an isDone getter, you hopefully use something like this to create the cell:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ProjectCell", forIndexPath: indexPath) as ProjectCell
let project = allProjects[indexPath.row]
if project.isDone {
cell.detailTextLabel?.text = "Done"
}
else {
cell.detailTextLabel?.text = nil
}
return cell
}
as you can see you decide depending on isDone if the "Done" text will be displayed.
So you can create a function that uses the same test to create an array that contains only projects that are done.
func projectsThatAreDone(allProjects: [Project]) -> [Project] {
let matchingProjects = allProjects.filter {
return $0.isDone
}
return matchingProjects
}
and you then use let doneProjects = projectsThatAreDone(allProjects)