提问人:Cristian Capannini 提问时间:7/7/2023 最后编辑:Cristian Capannini 更新时间:7/8/2023 访问量:73
SWIFT & Storyboard - 带有部分的表视图,每个部分都包含一个复选框列表
SWIFT & Storyboard - Tableview with Sections and each them contains a list of checkboxes
问:
Goodmornig,我需要一些帮助来显示带有部分的表视图和每个部分的自定义 tableviewcell。我希望实现这个目标,如下图所示:
从图片中我们了解到,如果选中了带有复选框及其 ID 的兴趣列表>类别。
我已经构建了 tableview 单元格,如下所示:
这是tableview的代码
class InteresseCell2: UITableViewCell {
@IBOutlet weak var checkBoxInteresse: CheckBoxButton!
@IBOutlet weak var labelInteresse: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
//MARK:- setDescrizioneInteresse
func setDescrizioneInteresse(_ descrizione: String)
{
self.labelInteresse.text = descrizione
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
其中 CheckBoxButton 是我的自定义类:
class CheckBoxButton: UIButton {
// Images
let checkedImage = UIImage(named: "box_checked")! as UIImage
let uncheckedImage = UIImage(named: "box_unchecked")! as UIImage
// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(uncheckedImage, for: .normal)
} else {
self.setImage(checkedImage, for: .normal)
}
}
}
override func awakeFromNib() {
self.isUserInteractionEnabled = true
self.addTarget(self, action: #selector(CheckBoxButton.buttonClicked), for: .touchUpInside)
self.isChecked = false
}
@objc func buttonClicked(sender: UIButton) {
if sender == self {
if isChecked == true {
isChecked = false
} else {
isChecked = true
}
}
}
}
我的json是这样形成的:
{
"success": 1,
"interessi": [
{
"cid": "1",
"categoria": "Marketing & Comunicazione",
"elenco": [
{
"id": "5",
"cid": "1",
"descrizione": "Advertising"
},
{
"id": "4",
"cid": "1",
"descrizione": "Branding"
},
{
"id": "2",
"cid": "1",
"descrizione": "Content creation"
},
{
"id": "6",
"cid": "1",
"descrizione": "Copywriting"
},
{
"id": "3",
"cid": "1",
"descrizione": "Influencer Marketing"
},
{
"id": "12",
"cid": "1",
"descrizione": "Media"
},
{
"id": "7",
"cid": "1",
"descrizione": "Personal Branding"
},
{
"id": "1",
"cid": "1",
"descrizione": "Social Media"
},
{
"id": "10",
"cid": "1",
"descrizione": "Strategy"
},
{
"id": "8",
"cid": "1",
"descrizione": "Sviluppo Prodotto"
},
{
"id": "9",
"cid": "1",
"descrizione": "Trade Marketing"
},
{
"id": "11",
"cid": "1",
"descrizione": "UX/Web & Graphic Design"
}
]
},
{
"cid": "2",
"categoria": "Sviluppo della persona",
"elenco": [
{
"id": "13",
"cid": "2",
"descrizione": "Coaching"
},
{
"id": "16",
"cid": "2",
"descrizione": "Counseling"
},
{
"id": "15",
"cid": "2",
"descrizione": "Crescita Personale"
},
{
"id": "14",
"cid": "2",
"descrizione": "Mentoring"
},
{
"id": "17",
"cid": "2",
"descrizione": "Orientamento Post-Universitario"
}
]
}
]
}
我的InteresseSection对象类是:
class InteresseSection: NSObject {
var categoria: String = String()
var interessi: [Interesse] = []
}
Interesse 类是:
class Interesse: NSObject {
var id: String = String()
var cid: String = String()
var descrizione: String = String()
}
获取json数据的代码如下
func getData() {
print("InteressiRegistrazioneVC getData")
DispatchQueue.main.async {
self.refreshControl.endRefreshing()
}
let getListaInteressiString = "\(Constants.GET_LISTA_INTERESSI_URL)"
let interessiURL: URL = URL(string: getListaInteressiString)!
var request = URLRequest(url: interessiURL)
request.httpMethod = "POST"
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
request.allHTTPHeaderFields = headers
let parameters: [String: Any] = [
"user_id": UserDefaults.standard.string(forKey: "user_id") ?? "-1",
"email": UserDefaults.standard.string(forKey: "email") ?? "[email protected]",
"r": "" // mettere il campo search ma è
]
request.httpBody = parameters.percentEncoded()
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {
print("InteressiRegistrazioneVC getData error: \(String(describing: error))")
DispatchQueue.main.async {
//self.hideLoading()
//self.isLoading = false
}
return
}
if let httpResponse = response as? HTTPURLResponse {
print("InteressiRegistrazioneVC getData status code: \(httpResponse.statusCode)")
if httpResponse.statusCode == 200 {
} else {
}
}
// converting data to string
if let dataAsString = String.init(data: data, encoding: String.Encoding.utf8) {
print("InteressiRegistrazioneVC getData dataAsString: \(dataAsString)")
}
do {
if let jsonDictionary = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String, Any> {
let interessiArray = jsonDictionary["interessi"] as? NSArray ?? []
self.allInteressi.removeAll()
if interessiArray.count == 0 {
DispatchQueue.main.async {
//self.noDataView.isHidden = false
//self.tableView.isHidden = true
}
} else {
DispatchQueue.main.async {
//self.tableView.isHidden = false
//self.noDataView.isHidden = true
}
for sezione in interessiArray {
if let dictionarySection = sezione as? [String: Any] {
let elenco = dictionarySection["elenco"] as? NSArray ?? []
var interessiInSection: [Interesse] = []
for itemElenco in elenco {
if let interesse = itemElenco as? [String: Any] {
let id = interesse["id"] as? String ?? ""
let cid = interesse["cid"] as? String ?? ""
let descrizione = interesse["descrizione"] as? String ?? ""
Logger.show(msg: "\n")
Logger.show(msg: "InteressiRegistrazioneVC item id: \(String(describing: id))")
Logger.show(msg: "InteressiRegistrazioneVC item cid: \(String(describing: cid))")
Logger.show(msg: "InteressiRegistrazioneVC item descrizione: \(String(describing: descrizione))")
let newInteresse = Interesse()
newInteresse.id = id
newInteresse.cid = cid
newInteresse.descrizione = descrizione
interessiInSection.append(newInteresse) // raccolgo tutti i prodotti presenti nella i-esima sezione
} // interesse itemelenco
} //elenco
let newSection = InteresseSection()
let categoria = dictionarySection["categoria"] as? String ?? ""
Logger.show(msg: "InteressiRegistrazioneVC getData categoria: \(categoria)")
newSection.categoria = categoria
newSection.interessi = interessiInSection
//self.allInteressi.append(newSection)
} // dictionary section
} // sezione
}
// aggiorno la tabella dopo aver scaricato i dati
DispatchQueue.main.async {
}
}
} catch let error as NSError {
print("InteressiRegistrazioneVC getData error: \(error)")
DispatchQueue.main.async {
}
}
// aggiorno la tabella dopo aver scaricato i dati
DispatchQueue.main.async {
}
}
task.resume()
}
如何显示包含复选框和标签的单元格部分的兴趣列表,如图所示?然后,当单击复选框时,收集选中的所有ID? 我使用tableview。 感谢您的帮助
答:
1赞
Chandaboy
7/7/2023
#1
这是代码,我已经在我的本地文件中使用了你的json替换它,为TopTitleHeader创建UIview(见截图),我也有附加屏幕,只需修复这些视图,你就可以开始了
class ViewController: UIViewController {
var feedbackArrayRec: [Interessi]?
@IBOutlet weak var tblview: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let object = showModeObject()
self.feedbackArrayRec = object?.interessi
self.tblview?.register(UINib.init(nibName: "TopTitleHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: "TopTitleHeader")
self.tblview?.register(UINib.init(nibName: "InteresseCell2", bundle: nil), forCellReuseIdentifier: "InteresseCell2")
self.tblview?.reloadData()
}
}
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 44.0
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?{
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "TopTitleHeader") as? TopTitleHeader
let contnetView = self.feedbackArrayRec?[section].categoria
headerView?.setContent(content: contnetView)
return headerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 54.0
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return .leastNonzeroMagnitude
}
}
extension ViewController:UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.feedbackArrayRec?[section].elenco.count ?? 0
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.feedbackArrayRec?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "InteresseCell2", for: indexPath) as! InteresseCell2
let objectValue = self.feedbackArrayRec?[indexPath.section].elenco[indexPath.row]
cell.setContentValue(contnet: objectValue)
return cell
}
}
func showModeObject() -> EventsRecords?
{
var tmpRec: EventsRecords?
if let path = Bundle.main.path(forResource: "fatca", ofType: "json")
{
do {
let jsonData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let decoder = JSONDecoder()
do {
let people = try decoder.decode(EventsRecords.self, from: jsonData)
tmpRec = people
} catch {
print(error)
}
}
catch {
// handle error
}
}
return tmpRec
}
struct EventsRecords: Codable {
let success: Int?
let interessi: [Interessi]?
}
// MARK: - Interessi
struct Interessi: Codable {
let cid, categoria: String?
let elenco: [Elenco]
}
// MARK: - Elenco
struct Elenco: Codable {
let id, cid, descrizione: String?
}
TopTileHeaderView
class TopTitleHeader: UITableViewHeaderFooterView {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
@IBOutlet weak var lblTxt: UILabel?
@IBOutlet weak var bgColor: UIView?
func setContent(content: String?)
{
self.lblTxt?.text = content
}
}
您的 InterseCell2 类
class InteresseCell2: UITableViewCell {
@IBOutlet weak var checkBoxInteresse: CheckBoxButton!
@IBOutlet weak var labelInteresse: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setContentValue(contnet: Elenco?)
{
self.labelInteresse.text = contnet?.descrizione
}
}
class CheckBoxButton: UIButton {
// Images
let checkedImage = UIImage(named: "check")! as UIImage
let uncheckedImage = UIImage(named: "Uncheck")! as UIImage
// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(uncheckedImage, for: .normal)
} else {
self.setImage(checkedImage, for: .normal)
}
}
}
override func awakeFromNib() {
self.isUserInteractionEnabled = true
self.addTarget(self, action: #selector(CheckBoxButton.buttonClicked), for: .touchUpInside)
self.isChecked = false
}
@objc func buttonClicked(sender: UIButton) {
if sender == self {
if isChecked == true {
isChecked = false
} else {
isChecked = true
}
}
}
}
评论
0赞
Cristian Capannini
7/7/2023
我的天啊!!谢谢@Chandaboy我会尝试的!
0赞
Cristian Capannini
7/8/2023
将我的 JSON 输入放在哪里?这里?if let path = Bundle.main.path(forResource: “fatca”, ofType: “json”) ?
0赞
Chandaboy
7/8/2023
只需将文件放入您的项目中即可。这是示例JSON文件
0赞
Cristian Capannini
7/8/2023
嗯,我没有文件,但 json 是从后端 php 给出的,我使用了代码中添加的函数 getData() @chandaboy
0赞
Cristian Capannini
7/8/2023
我已将源代码粘贴到粘贴箱 pastebin.com/M8KaSvpA 中。对象返回 nil
评论