Custom UITable View Headers disappear after reloading a specific table view cell - ios

I have a tableview with custom headers. and the uitableview row cells have refresh button that will call an API and reload the sender cell. However, whenever a refresh is done, the section headers disappear.
extension AccountViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else {
return platforms.count - 1
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "BalanceHeaderCell") as? BalanceHeaderCell
if self.currentUser != nil {
self.saveUserDefault(item: currentUser?.balance ?? "", key: Account.accountBalanceRecord)
cell?.headerRefreshButton.tag = section
cell?.headerRefreshButton.addTarget(self, action: #selector(refreshAccountBalanceInfo), for: UIControlEvents.touchUpInside)
cell?.set(user: self.currentUser!)
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "PlatformHeaderCell") as? PlatformHeaderCell
return cell
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "BankCardsCell", for: indexPath) as? BankCardsCell
cell?.setCell(bankCount: self.bankCount)
return cell!
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "PlatformListCell", for: indexPath) as? PlatformListCell
cell?.set(platforms: platforms[indexPath.row])
cell?.platformRefreshButton.tag = indexPath.row
cell?.platformRefreshButton.addTarget(self, action: #selector(refreshPlatformBalanceInfo), for: UIControlEvents.touchUpInside)
return cell!
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return 73
} else {
return 40
}
}
What are your suggestions?

Related

How to add header to each row in a table view

I'm building an iOS app with a collection view inside the table view. I'm having three rows each row having a collection view inside it. I am planning to have three sections each section for each row. For example row, one should be in a separate section with a header and similarly for rows 2 and 3.
Whenever I create three sections I'm getting all the three rows in all three sections. I want to have a separate section with a header for each row.
import UIKit
class StoreVC: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var CourseTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
CourseTableView.tableFooterView = UIView()
CourseTableView.delegate = self
CourseTableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0
{
return "Courses"
}
else if section == 1
{
return "Tests"
}
return "Bundles"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CourseRow
return cell
}
else if indexPath.row == 1
{
let cell = tableView.dequeueReusableCell(withIdentifier: "testcell", for: indexPath) as! TestRow
return cell
}
else if indexPath.row == 2
{
let cell = tableView.dequeueReusableCell(withIdentifier: "bundlecell", for: indexPath) as! BundleRow
return cell
}
return UITableViewCell()
}
}
Try this code on your Xcode-playground and customize as you need.
import UIKit
import PlaygroundSupport
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UILabel()
headerView.text = "Header: \(section)"
return headerView
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Cell: \(indexPath)"
return cell
}
}
PlaygroundPage.current.liveView = ViewController()

Tableview header cell expand with same cardView in swift?

I have attached the image click the card view expands the same card inside the table cell dynamically its passible to achieve this?
I have searched a lot but not working
Hear my code added header cell with CardView
added arrow button to click the button expand the cell
its able expand but not in parent card it was showing diff card
I have adde my source code
var hiddenSections = Set<Int>()
let tableViewData = [
["1","2","3","4","5"],
["1","2","3","4","5"],
["1","2","3","4","5"],
]
override func viewDidLoad() {
super.viewDidLoad()
let CustomeHeaderNib = UINib(nibName: "CustomSectionHeader", bundle: Bundle.main)
historyTableView.register(CustomeHeaderNib, forHeaderFooterViewReuseIdentifier: "customSectionHeader")
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.tableViewData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.hiddenSections.contains(section) {
return 0
}
return self.tableViewData[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = self.tableViewData[indexPath.section][indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return view.frame.width/4
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = self.historyTableView.dequeueReusableHeaderFooterView(withIdentifier: "customSectionHeader") as! CustomSectionHeader
header.setupCornerRadious()
let sectionButton = header.expandBtn
sectionButton?.setTitle(String(section),
for: .normal)
sectionButton?.tag = section
sectionButton?.addTarget(self,action: #selector(self.hideSection(sender:)), for: .touchUpInside)
return header
}
#objc
private func hideSection(sender: UIButton) {
let section = sender.tag
func indexPathsForSection() -> [IndexPath] {
var indexPaths = [IndexPath]()
for row in 0..<self.tableViewData[section].count {
indexPaths.append(IndexPath(row: row,
section: section))
}
return indexPaths
}
if self.hiddenSections.contains(section) {
self.hiddenSections.remove(section)
self.historyTableView.insertRows(at: indexPathsForSection(),
with: .fade)
} else {
self.hiddenSections.insert(section)
self.historyTableView.deleteRows(at: indexPathsForSection(),
with: .fade)
}
}
With out sections also you can achieve this. To do this,
1.Return cell height as section height. If user clicks on the cell then return total content height to the particular cell.
2.You need to take an array, if user selects cell, add indexPath number in to array. If selects already expand cell remove it from array. In height for row at index check indexPath is in array or not.
This is one of the way. With sections also you can do that.
//MARK:- UITableView Related Methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrDict.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// var cel = tblExpandedTest.dequeueReusableCellWithIdentifier("expCell", forIndexPath: indexPath) as! CDTableViewCell
var cel : CaseHearingTabTVC! = tableView.dequeueReusableCell(withIdentifier: "caseHearingTabCell") as! CaseHearingTabTVC
if(cel == nil)
{
cel = Bundle.main.loadNibNamed("caseHearingTabCell", owner: self, options: nil)?[0] as! CaseHearingTabTVC;
}
//cell?.backgroundColor = UIColor.white
cel.delegate = self
if indexPath != selctedIndexPath{
cel.subview_desc.isHidden = true
cel.subview_remarks.isHidden = true
cel.lblHearingTime.isHidden = true
}
else {
cel.subview_desc.isHidden = false
cel.subview_remarks.isHidden = false
cel.lblHearingTime.isHidden = false
}
return cel
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectIndex = true;
if(selectedInd == indexPath.row) {
selectedInd = -1
}
else{
let currentCell = tableView.cellForRow(at: indexPath)! as! CaseHearingTabTVC
cellUpdatedHeight = Float(currentCell.lblHearingTime.frame.origin.y + currentCell.lblHearingTime.frame.size.height) + 2;
selectedInd = -1
tblCaseHearing.reloadData()
selectedInd = indexPath.row
}
let previousPth = selctedIndexPath
if indexPath == selctedIndexPath{
selctedIndexPath = nil
}else{
selctedIndexPath = indexPath
}
var indexPaths : Array<IndexPath> = []
if let previous = previousPth{
indexPaths = [previous]
}
if let current = selctedIndexPath{
indexPaths = [current]
}
if indexPaths.count>0{
tblCaseHearing.reloadRows(at: indexPaths, with: UITableView.RowAnimation.automatic)
}
}
func tableView(_ tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowIndexPath indexPath:IndexPath) {
(cell as! CaseHearingTabTVC).watchFrameChanges()
}
func tableView(_ tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowIndexPath indexPath:IndexPath) {
(cell as! CaseHearingTabTVC).ignoreFrameChanges()
}
func tableView(_ TableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
if indexPath == selctedIndexPath{
return CGFloat(cellUpdatedHeight)
}else{
return CaseHearingTabTVC.defaultHeight
}
}
Best approach is to create two different cells for normal card and expanded card.
fileprivate var selectedIndex: Int?
func registerTableViewCells() {
tableView.register(UINib(nibName:Nib.CardCell , bundle: nil), forCellReuseIdentifier: "CardCell")
tableView.register(UINib(nibName:Nib.ExpandedCardCell , bundle: nil), forCellReuseIdentifier: "ExpandedCardCell")
}
override func viewDidLoad() {
super.viewDidLoad()
self.registerTableViewCells()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let index = selectedIndex else {
return 115
}
if index == indexPath.row{
return 200
}
return 115
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let selected = selectedIndex, selected == indexPath.row{
let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandedCardCell", for: indexPath) as! ExpandedCardCell
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath) as! CardCell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedIndex == indexPath.row{
selectedIndex = nil
}
else{
selectedIndex = indexPath.row
}
UIView.performWithoutAnimation {
tableView.reloadData()
}
}

I want to set tick in tableview cell for row at indexpath

i am adding multiple selection in tableview with sections in tableview, so how can i store that section index as well as indexpath of that cell for display when user click on cell inside that particular sections that will store in array as selected item and reflect in cellForRowAtindexpath the better solution is appreciated
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemsInSections[section].count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.sections.count;
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header = view as! UITableViewHeaderFooterView
header.textLabel?.textColor = UIColor(red: 8/255, green: 38/255, blue: 76/255, alpha: 1.0)
header.backgroundColor = UIColor.clear
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tablheaders.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
let section = indexPath.section
if checkdarray.count > 0
{
if (self.checkdarray[section][indexPath.row] as Int == 1)
{
cell.accessoryType = .checkmark;
}
else
{
cell.accessoryType = .none;
}
}
cell.textLabel?.text = itemsInSections[indexPath.section][indexPath.row] as! String
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let section = indexPath.section as Int
let indepaths = indexPath.row as Int
tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
checkdarray.insert([1], at: [section][indepaths])
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
// checkdarray.remove(at: indexPath.row)
//checkdarray.insert(0, at: indexPath.row)
}
The most efficient and reliable solution is to keep the isSelected state in the data model.
Use a struct as data model and add a member isSelected along with the other information you need.
struct Model {
var isSelected = false
var someOtherMember : String
// other declarations
}
In cellForRow set the checkmark according to the isSelected member
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) // use always the passed tableView instance
let model = itemsInSections[indexPath.section][indexPath.row]
cell.accessoryType = model.isSelected ? .checkmark : .none
cell.textLabel?.text = model.someOtherMember
return cell
}
In didSelectRowAt and didDeselectRowAt update the model and reload the row
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
itemsInSections[indexPath.section][indexPath.row].isSelected = true
tableView.reloadRows(at: [indexPath], with: .none)
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
itemsInSections[indexPath.section][indexPath.row].isSelected = false
tableView.reloadRows(at: [indexPath], with: .none)
}
Never use an extra array to save index paths. Don't do that.
I have used button in table...
// declare var
var checkarrMenu = Set<IndexPath>()
// In tableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = mManageTableView.dequeueReusableCell(withIdentifier: "TableViewCellID")as! TableViewCell
cell.mRadioBtnAct.tag = indexPath.row
cell.mRadioBtnAct.addTarget(self, action: #selector(mRadioCheck(sender:)), for: .touchUpInside)
if checkarrMenu.contains(indexPath){
cell.mradioimage.image = UIImage(named: "Radiochecked")
}else{
cell.mradioimage.image = UIImage(named: "Radio checkedlightRadio3")
}
return cell
}
// on radio btn Action
#objc func mRadioCheck(sender:UIButton){
let touchPoint: CGPoint = sender.convert(CGPoint.zero, to: mManageTableView)
// maintable --> replace your tableview name
let clickedButtonIndexPath = mManageTableView.indexPathForRow(at: touchPoint)
if checkarrMenu.contains(clickedButtonIndexPath){
checkarrMenu.remove(clickedButtonIndexPath)
}else{
checkarrMenu.insert(clickedButtonIndexPath)
}
tableView.reloadData()
}
// hope its works for you!

iOS: How to create Expandable TableView in Swift without using Third party libraries or pods

I have Implemented Tableview in swift, but I want to Make an Expandable TableView, please give me an idea.
This is the code for Tableview,
//MARK: - TableView Delegate and Datasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return MenuNameArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MenuTableViewCell", for: indexPath) as! MenuTableViewCell
cell.menuNameLabel.text = NameArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
Here You Go , Try This Out : -
struct ExpandableNames {
var isExpanded : Bool
var names : [String]
}
struct Contact {
let names : String
}
in your Class - >
var twoDArray = [
ExpandableNames(isExpanded : true,names:["Krishna","Rishabh","Aditya","Chandan","Nipun","Navdeesh","Steve"].map
{
Contact(names: $0)
}),
ExpandableNames(isExpanded : true,names:["Carl","Michal","Tommy","Jennny","Vikram","Swati"].map
{
Contact(names: $0)
}),
ExpandableNames(isExpanded : true,names:["David","dude","dfff","dcc","daa","dee","dsss"].map
{
Contact(names: $0)
}),
ExpandableNames(isExpanded : true,names:[Contact(names: "Pattrick", hasFav: false)])
]
let cellId = "cellID"
let identifier = "attachmentCellID"
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return 50
}
func numberOfSections(in tableView: UITableView) -> Int
{
return twoDArray.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if !twoDArray[section].isExpanded
{
return 0
}
return twoDArray[section].names.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let btn = UIButton(type: .system)
if(section == 0)
{
btn.setTitle("Tap To View Classes", for: .normal)
}
else if(section == 1)
{
btn.setTitle("Tap To View Admins", for: .normal)
}
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
btn.addTarget(self, action: #selector(handleExpandClose), for: .touchUpInside)
btn.backgroundColor = AppColors.greyBorderColor
btn.tag = section
return btn
}
#objc func handleExpandClose(button : UIButton)
{
let section = button.tag
var indexPaths = [IndexPath]()
for row in twoDArray[section].names.indices
{
let indexPath = IndexPath(row: row, section: section)
indexPaths.append(indexPath)
}
let isExpanded = twoDArray[section].isExpanded
twoDArray[section].isExpanded = !isExpanded
button.setTitle(isExpanded ? "Tap To View Classes" : "Classes", for: .normal)
if isExpanded
{
tableView.deleteRows(at: indexPaths, with: .fade)
}
else
{
tableView.insertRows(at: indexPaths, with: .fade)
}
}
And Rest in cellForRowAt -
let contact = twoDArray[indexPath.section].names[indexPath.row]
cell.textLabel?.text = contact.names
First you will need a model defining if the cell is open, for example, an array of indexPaths:
var openPaths = [IndexPath]()
now when select the cell you toggle wether it is open or not and reload the cell
if let index = openPaths.index(indexPath) {
openPaths.remove(atIndex: index)
} else {
openPaths.append(indexPath)
}
tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
Now in your cell setup, use a stackview, and in the cell config, you hide the expandable part based on if the cells indexPath is in openPaths
Use heightForRowAt delegate method to change height of cell:-
Add a boolean property to your object say isExpanded, change the value in
didSelectRowAt delegate by
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
YourModel[indexPath.row].isExpanded = !YourModel[indexPath.row].isExpanded
tableView.reloadRows(at: [indexPath], with: Animation)
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if YourModel[indexPath.row].isExpanded {
return 200
} else {
return 50
}
}

Use segmentcontroller to change tableview

I want to use XMSegmentController(https://cocoapods.org/?q=segmen) to change the different tableview,I do not know what is missing in my program, which leads to a black situation when I run. Does anyone know what to add to my program? Thank you.
Here is mt code:
import UIKit
import XMSegmentedControl
class ViewController: UIViewController, XMSegmentedControlDelegate,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var segmentedControl1: XMSegmentedControl!
#IBOutlet weak var tableview1: UITableView!
#IBOutlet weak var tableview2: UITableView!
let one = ["1","2","3"]
let two = ["4","5","6"]
override func viewDidLoad() {
super.viewDidLoad()
segmentedControl1.delegate = self
segmentedControl1.segmentTitle = ["One", "Two"]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "left", for: indexPath)
cell.textLabel?.text = one[indexPath.row]
return cell
}else {
let cell = tableView.dequeueReusableCell(withIdentifier: "right", for: indexPath)
cell.textLabel?.text = two[indexPath.row]
return cell
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.tableview1 {
return one.count
}
return two.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func xmSegmentedControl(_ xmSegmentedControl: XMSegmentedControl, selectedSegment: Int) {
if xmSegmentedControl == segmentedControl1 {
print("SegmentedControl1 Selected Segment: \(selectedSegment)")
}
}
}
Set your controller as initial ViewController to show your Controller. Now use selectedSegment argument from delegate method and hide/show the tableView according to it.
func xmSegmentedControl(_ xmSegmentedControl: XMSegmentedControl, selectedSegment: Int) {
if xmSegmentedControl == segmentedControl1 {
tableview1.isHidden = selectedSegment != 0
tableview2.isHidden = selectedSegment != 1
}
}
Also instead of using two tableView you can use single tableView like this.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if segmentedControl1.selectedSegment == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "left", for: indexPath)
cell.textLabel?.text = one[indexPath.row]
return cell
}else {
let cell = tableView.dequeueReusableCell(withIdentifier: "right", for: indexPath)
cell.textLabel?.text = two[indexPath.row]
return cell
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if segmentedControl1.selectedSegment == 0 {
return one.count
}
return two.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
And in delegate method of xmSegmentedControl simply reload the tableView.
func xmSegmentedControl(_ xmSegmentedControl: XMSegmentedControl, selectedSegment: Int) {
if xmSegmentedControl == segmentedControl1 {
tableView.reloadData()
}
}
what is your initial ViewController?can you please check in your storyboard?
set an initial viewcontroller.
func xmSegmentedControl(_ xmSegmentedControl: XMSegmentedControl, selectedSegment: Int) {
if xmSegmentedControl == segmentedControl1 {
tableviewOne.isHidden = selectedSegment != 0
tableviewSecond.isHidden = selectedSegment != 1
}
}

Resources