Skip to content

Instantly share code, notes, and snippets.

@DonMag
Created June 16, 2022 13:46
Show Gist options
  • Save DonMag/de46dde832e6770967c40afd625b68bb to your computer and use it in GitHub Desktop.
Save DonMag/de46dde832e6770967c40afd625b68bb to your computer and use it in GitHub Desktop.
Basic Swift iOS example of collection view in a table view cell
// assign table view controller custom class to:
// DonMagSampleTableViewController
// no cell Prototypesneeded
// no @IBOutlet or @IBAction connections needed
struct DonMagSampleDataStruct {
var color: UIColor = .white
var strings: [String] = []
}
class DonMagSampleTableViewController: UITableViewController {
var myData: [DonMagSampleDataStruct] = []
override func viewDidLoad() {
super.viewDidLoad()
let sample: [String] = [
"Label - A label can contain an arbitrary amount of text, but UILabel may shrink, wrap, or truncate the text, depending on the size of the bounding rectangle and properties you set. You can control the font, text color, alignment, highlighting, and shadowing of the text in the label.",
"Button - You can set the title, image, and other appearance properties of a button. In addition, you can specify a different appearance for each button state.",
"Segmented Control - The segments can represent single or multiple selection, or a list of commands. Each segment can display text or an image, but not both.",
"Text Field - Displays a rounded rectangle that can contain editable text. When a user taps a text field, a keyboard appears; when a user taps Return in the keyboard, the keyboard disappears and the text field can handle the input in an application-specific way. UITextField supports overlay views to display additional information, such as a bookmarks icon. UITextField also provides a clear text control a user taps to erase the contents of the text field.",
"Slider - UISlider displays a horizontal bar, called a track, that represents a range of values. The current value is shown by the position of an indicator, or thumb. A user selects a value by sliding the thumb along the track. You can customize the appearance of both the track and the thumb.",
"Switch - Displays an element that shows the user the boolean state of a given value. By tapping the control, the state can be toggled.",
"Activity Indicator View - Used to indicate processing for a task with unknown completion percentage.",
"Progress View - Shows that a lengthy task is underway, and indicates the percentage of the task that has been completed.",
"Page Control - UIPageControl indicates the number of open pages in an application by displaying a dot for each open page. The dot that corresponds to the currently viewed page is highlighted. UIPageControl supports navigation by sending the delegate an event when a user taps to the right or to the left of the currently highlighted dot.",
"Stepper - Often combined with a label or text field to show the value being incremented.",
"Horizontal Stack View - An UIStackView creates and manages the constraints necessary to create horizontal or vertical stacks of views. It will dynamically add and remove its constraints to react to views being removed or added to its stack. With customization it can also react and influence the layout around it.",
"Vertical Stack View - An UIStackView creates and manages the constraints necessary to create horizontal or vertical stacks of views. It will dynamically add and remove its constraints to react to views being removed or added to its stack. With customization it can also react and influence the layout around it.",
"Table View - Coordinates with a data source and delegate to display a scrollable list of rows. Each row in a table view is a UITableViewCell object. The rows can be grouped into sections, and the sections can optionally have headers and footers. The user can edit a table by inserting, deleting, and reordering table cells.",
"Table View Cell - Defines the attributes and behavior of cells in a table view. You can set a table cell's selected-state appearance, support editing functionality, display accessory views (such as a switch control), and specify background appearance and content indentation.",
"Image View - Shows an image, or series of images as an animation.",
"Collection View - Coordinates with a data source and delegate to display a scrollable collection of cells. Each cell in a collection view is a UICollectionViewCell object. Collection views support flow layout as well a custom layouts, and cells can be grouped into sections, and the sections and cells can optionally have supplementary views.",
"Collection View Cell - A single view representing one cell in a collection view. Populate it with subviews, like labels and image views, to provide appearance.",
"Collection View Reusable View - Defines the attributes and behavior of reusable views in a collection view, such as a section header or footer.",
"Text View - When a user taps a text view, a keyboard appears; when a user taps Return in the keyboard, the keyboard disappears and the text view can handle the input in an application-specific way. You can specify attributes, such as font, color, and alignment, that apply to all text in a text view.",
"Scroll View - UIScrollView provides a mechanism to display content that is larger than the size of the application’s window and enables users to scroll within that content by making swiping gestures.",
"Date Picker - Provides an object that uses multiple rotating wheels to allow users to select dates and times. Examples of a date picker are the Timer and Alarm (Set Alarm) panes of the Clock application. You may also use a UIDatePicker as a countdown timer.",
"Picker View - Provides a potentially multidimensional user-interface element consisting of rows and components. A component is a wheel, which has a series of items (rows) at indexed locations on the wheel. Each row on a component has content, which is either a string or a view object such as a label or an image.",
]
let colors: [UIColor] = [
.systemRed, .systemGreen, .systemBlue, .cyan, .magenta, .yellow,
.red, .green, .blue, .orange, .brown, .purple,
]
for (idx, s) in sample.enumerated() {
let c = colors[idx % colors.count]
let a1: [String] = s.components(separatedBy: " - ")
let a: [String] = [a1[0] + ":"] + a1[1].components(separatedBy: " ")
let d = DonMagSampleDataStruct(color: c, strings: a)
myData.append(d)
}
tableView.register(DonMagSampleTableCell.self, forCellReuseIdentifier: "c")
tableView.dataSource = self
tableView.delegate = self
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath) as! DonMagSampleTableCell
cell.rowTitleLabel.text = "Row \(indexPath.row)"
cell.thisData = myData[indexPath.row]
cell.didSelectClosure = { [weak self] c in
guard let self = self,
let idx = tableView.indexPath(for: c)
else { return }
tableView.selectRow(at: idx, animated: true, scrollPosition: .none)
self.myTableView(tableView, didSelectRowAt: idx)
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
myTableView(tableView, didSelectRowAt: indexPath)
}
func myTableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("My tableView didSelectRowAt:", indexPath)
}
}
class DonMagSampleTableCell: UITableViewCell {
public var didSelectClosure: ((UITableViewCell) ->())?
var rowTitleLabel: UILabel!
var collectionView: UICollectionView!
var thisData: DonMagSampleDataStruct = DonMagSampleDataStruct() {
didSet {
collectionView.reloadData()
}
}
override func prepareForReuse() {
collectionView.contentOffset.x = 0
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
let fl = UICollectionViewFlowLayout()
fl.scrollDirection = .horizontal
fl.estimatedItemSize = CGSize(width: 120, height: 50)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: fl)
collectionView.backgroundColor = .systemYellow
collectionView.register(DonMagSampleCollectionCell.self, forCellWithReuseIdentifier: "c")
collectionView.dataSource = self
collectionView.delegate = self
rowTitleLabel = UILabel()
rowTitleLabel.translatesAutoresizingMaskIntoConstraints = false
collectionView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(rowTitleLabel)
contentView.addSubview(collectionView)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
rowTitleLabel.topAnchor.constraint(equalTo: g.topAnchor),
rowTitleLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor),
rowTitleLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: rowTitleLabel.bottomAnchor, constant: 8.0),
collectionView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
collectionView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
collectionView.heightAnchor.constraint(equalToConstant: 70.0),
])
}
}
extension DonMagSampleTableCell: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return thisData.strings.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "c", for: indexPath) as! DonMagSampleCollectionCell
cell.label.text = thisData.strings[indexPath.item]
cell.contentView.backgroundColor = thisData.color
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("collectionView didSelecteItemAt:", indexPath)
print("Calling closure...")
didSelectClosure?(self)
}
}
class DonMagSampleCollectionCell: UICollectionViewCell {
var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
label = UILabel()
label.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
label.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(label)
contentView.layoutMargins = UIEdgeInsets(top: 16, left: 20, bottom: 16, right: 20)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: g.topAnchor),
label.leadingAnchor.constraint(equalTo: g.leadingAnchor),
label.trailingAnchor.constraint(equalTo: g.trailingAnchor),
label.bottomAnchor.constraint(equalTo: g.bottomAnchor),
])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment