I have given constraints for image and label like this
我给出了这样的形象和标签的约束
Image constraints. Label Constraints
图像约束。标签约束
code: with this code i am able to get selectedNamesArray
but unable to change cell colour. where am i wrong? is there anything wrong in storyboard constraints so that cell BG is not changing? or any other coding mistake? could anyone please explain the issue and the solution for cell background change
代码:使用此代码,我可以选择名称数组,但不能更改单元格颜色。我哪里错了?故事板约束有什么问题吗?这样单元格BG就不会改变?或任何其他编码错误?有没有人能解释一下单元格背景变化的问题和解决办法
class TestCollectionCell: UICollectionViewCell{
@IBOutlet weak var roundImg: UIImageView!
@IBOutlet weak var titleLbl: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
roundImg.layer.cornerRadius = roundImg.frame.width / 2
roundImg.contentMode = .scaleToFill
roundImg.clipsToBounds = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
let layOut = UICollectionViewFlowLayout()
layOut.scrollDirection = .vertical
collectionView.collectionViewLayout = layOut
collectionView.allowsMultipleSelection = true
GenericCodableServicecall()
}
var cvWidth: CGFloat = -1.0
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if cvWidth != collectionView.frame.size.width {
cvWidth = collectionView.frame.size.width
if let fl = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
let nColumns: Int = 4
let sideSpace: CGFloat = fl.sectionInset.left + fl.sectionInset.right
let totalEmptyspace: CGFloat = sideSpace + (CGFloat(nColumns) * 3.0)
let w = (cvWidth - totalEmptyspace) / CGFloat(nColumns)
fl.itemSize = .init(width: w, height: w)
fl.minimumInteritemSpacing = 0.0
}
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
namesArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TestCollectionCell", for: indexPath) as! TestCollectionCell
cell.layoutIfNeeded()
cell.titleLbl.text = namesArray[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("in select..")
let cell = collectionView.cellForItem(at: indexPath) as! TestCollectionCell
let selectedName = namesArray[indexPath.row]
if let inx = selectedNamesArray.firstIndex(of: selectedName){
selectedNamesArray.remove(at: inx)
cell.backgroundColor = UIColor.red
}
else{
selectedNamesArray.append(selectedName)
cell.backgroundColor = UIColor.yellow
}
print(selectedNamesArray)
}
unable to change cell background when i select/deselect always showing green background only.
当我选择/取消选择始终仅显示绿色背景时,无法更改单元格背景。
EDIT:
编辑:
// MARK: - TestAPIModel
struct TestAPIModel: Codable {
let page, perPage, total, totalPages: Int
var data: [Datum]
let support: Support
enum CodingKeys: String, CodingKey {
case page
case perPage = "per_page"
case total
case totalPages = "total_pages"
case data, support
}
}
// MARK: - Datum
struct Datum: Codable {
let id: Int
let name: String
let year: Int
let color, pantoneValue: String
var isSelected: Bool = false
enum CodingKeys: String, CodingKey {
case id, name, year, color
case pantoneValue = "pantone_value"
case isSelected = "is_selected"
}
}
after changing model like above o/p:
如上图所示,更换机型后:
decodingFailed(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "is_selected", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "is_selected", intValue: nil) ("is_selected").", underlyingError: nil)))))
this is my serviceCAll case here how to check nil data please guide
这是我的服务Call Case在这里如何检查空数据请指导
var jsonData: TestAPIModel? {
didSet{
print(jsonData?.data)
}
Var jsonData:测试APIModel?{didSet{print(jsonData?.data)}
}
NetworkService.request("https://reqres.in/api/unknown", method: .get, parameters: parameters) { (result: Result<TestAPIModel, APIError>) in
switch result {
case .success(let user):
print("response \(user)")
self.jsonData = user
self.collectionView.reloadData()
case .failure(let error):
print("Error: \(error)")
}
}
更多回答
优秀答案推荐
An extra array for the selected
state is very bad practice. It's cumbersome to maintain and you have to set the color accordingly in cellForItemAt
because cells are reused when the user scrolls.
为所选状态添加额外的数组是非常糟糕的做法。它维护起来很麻烦,而且您必须在cell ForItemAt中相应地设置颜色,因为当用户滚动时,单元格会被重用。
A better way is a struct for the data source with a member isSelected
一种更好的方法是为数据源创建一个结构,其中成员为isSelected
struct Person {
let name: String
var isSelected = false
}
Then the data source array is
则数据源数组为
var people = [Person]()
and the data source and methods are
数据源和方法为
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
people.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TestCollectionCell", for: indexPath) as! TestCollectionCell
cell.layoutIfNeeded()
let person = people[indexPath.row]
cell.titleLbl.text = person.name
cell.backgroundColor = person.isSelected ? .red : .yellow
return cell
}
In didSelect
just toggle isSelected
of the item at given indexPath
and reload the item
在didSelect中,只需在给定的indexPath处切换项的isSelected并重新加载项
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("in select..")
people[indexPath.row].isSelected.toggle()
collectionView.reloadItems(at: [indexPath])
}
Try
尝试
let cell = collectionView.cellForItem(at: indexPath) as! TestCollectionCell
cell.contentView.backgroundColor = UIColor.white (What ever color u want change)
更多回答
here you have created Person
struct. but i have added namesArray with JSON DATA
like this self.namesArray = user.data.compactMap { $0.name }
. so where should i add isSelected
variable?
在这里您已经创建了Person结构。但是我已经添加了带有JSON数据的名称数组,比如self.name Array=user.data.comactMap{$0.name}。那么,我应该在哪里添加isSelected变量呢?
i have updated my code with Model and o/p
我已经使用Model和O/P更新了代码
In the object representing an item in data
. Add CodingKeys
and omit isSelected
because it's not part of the JSON and delete .compactMap { $0.name }
.
在表示数据中的项的对象中。添加CodingKeys并省略选择,因为它不是JSON的一部分,并删除.comactMap{$0.name}。
is it possible to add isSelected in jsonModel? or should i create new struct with name and isSelected
variables?
可以在jsonModel中添加isSelected吗?或者我应该用名称和isSelected变量创建新的结构?
Yes, delete case isSelected = "is_selected"
in the CodingKeys. A new struct is not needed.
是的,删除CodingKeys中的大小写isSelected=“is_Selected”。不需要新的结构。
your code also correct.. but i cant upvote
您的代码也是正确的。但我不能投赞成票
Although this code might answer the question, I recommend that you also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
虽然这段代码可能会回答这个问题,但我建议您也解释一下代码的作用以及它是如何解决问题的。带有解释的答案通常更有帮助,质量更好,更有可能吸引人们的好评。
我是一名优秀的程序员,十分优秀!