我想更改图像在 UICollectionView 中点击时,实际上图像正在改变,但不在正确的位置
I Want to change An Image On tap in UICollection View, Actually Image is Changing, But Not At right Place
我正在尝试在 collection 视图中点击更改 selected 和 unselected 图像,但是如果我 select 但是从第一个索引开始反映在其他指数中。我一次只想要一个 selection,但它也反映在其他部分。
这是我的 collection 视图结构。
struct teamSelected {
var logoImage: String
var isImageSelected: Bool
}
我为 currentIndex
创建了一个变量
var currentIndex : Int = 0
我的 collection 视图的数据如下所示:
var teamSelectionList: [teamSelected] = [
teamSelected(logoImage: "ic_team_yellow_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_red_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_purple_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_blue_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_green_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_orange_big", isImageSelected: false)
]
这是我的 collection 查看方法:
extension TeamViewController : UICollectionViewDelegate , UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return teamSelectionList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let teamSelection : TeamSelectionCollectionViewCell = self.teamCollectionView.dequeueReusableCell(withReuseIdentifier: "teamCell", for: indexPath) as! TeamSelectionCollectionViewCell
let row = teamSelectionList[indexPath.row]
teamSelection.logoImage.image = UIImage(named: row.logoImage)
teamSelection.logoButton.isSelected = row.isImageSelected
//teamSelection.logoButton.layer.setValue(row, forKey: "index")
teamSelection.logoButton.tag = indexPath.row
teamSelection.logoButton.addTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
teamSelection.seperatorView.isHidden = indexPath.row == 2 || indexPath.row == self.teamSelectionList.count - 1 ? true : false
return teamSelection
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: (teamCollectionView.frame.width / 3), height: 110.0)
}
@objc func logoButtonTapped(sender: UIButton){
// self.teamSelectionList[sender.tag].isImageSelected = true
// self.teamSelectionList[self.currentIndex].isImageSelected = self.currentIndex != sender.tag ? false : true
self.currentIndex = sender.tag
if (teamSelectionList[self.currentIndex].isImageSelected == false){
teamSelectionList[self.currentIndex].isImageSelected = true
sender.setImage(UIImage(named: "ic_radio_selected"), for: UIControl.State.normal)
} else {
teamSelectionList[self.currentIndex].isImageSelected = false
sender.setImage(UIImage(named: "ic_radio_normal"), for: UIControl.State.normal)
}
self.teamCollectionView.reloadData()
}
}
这是我得到的输出:
您在点击后使用 sender.setImage
更新选择图像。集合视图重复使用单元格,不能保证在下一个布局中使用相同的单元格。
我建议您将其从 logoButtonTapped
移至 cellForItemAt
,例如:
teamSelection.logoButton.isSelected = row.isImageSelected
teamSelection.logoButton.setImage(
UIImage(named: row.isImageSelected ? "ic_radio_normal" : "ic_radio_selected"),
for: UIControl.State.normal
)
还有一些提示。
- 根据 swift 代码风格指南,类 和结构的名称以大写字母开头并使用驼峰式大小写,例如
struct TeamSelected
而不是 struct teamSelected
。当您了解您是在调用函数还是 class/struct 构造函数时,阅读起来会容易得多。
- 存储选定的索引比存储每个项目的选择状态要容易得多。它需要更少的代码并降低错误概率。您的代码可以这样更新:
class TeamViewController: UIViewController {
let teamLogoList = [
"ic_team_yellow_big",
"ic_team_red_big",
"ic_team_purple_big",
"ic_team_blue_big",
"ic_team_green_big",
"ic_team_orange_big",
]
var selection = Set<Int>()
}
extension TeamViewController : UICollectionViewDelegate , UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return teamLogoList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let teamSelection : TeamSelectionCollectionViewCell = self.teamCollectionView.dequeueReusableCell(withReuseIdentifier: "teamCell", for: indexPath) as! TeamSelectionCollectionViewCell
let index = indexPath.row
teamSelection.logoImage.image = UIImage(named: teamLogoList[index])
let isImageSelected = selection.contains(index)
teamSelection.logoButton.isSelected = isImageSelected
teamSelection.logoButton.setImage(
UIImage(named: isImageSelected ? "ic_radio_normal" : "ic_radio_selected"),
for: UIControl.State.normal
)
//teamSelection.logoButton.layer.setValue(row, forKey: "index")
teamSelection.logoButton.tag = indexPath.row
teamSelection.logoButton.addTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
teamSelection.seperatorView.isHidden = indexPath.row == 2 || indexPath.row == self.teamLogoList.count - 1 ? true : false
return teamSelection
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: (teamCollectionView.frame.width / 3), height: 110.0)
}
@objc func logoButtonTapped(sender: UIButton){
let index = sender.tag
if (selection.contains(index)){
selection.remove(index)
} else {
selection.insert(index)
}
self.teamCollectionView.reloadData()
}
}
我正在尝试在 collection 视图中点击更改 selected 和 unselected 图像,但是如果我 select 但是从第一个索引开始反映在其他指数中。我一次只想要一个 selection,但它也反映在其他部分。
这是我的 collection 视图结构。
struct teamSelected {
var logoImage: String
var isImageSelected: Bool
}
我为 currentIndex
var currentIndex : Int = 0
我的 collection 视图的数据如下所示:
var teamSelectionList: [teamSelected] = [
teamSelected(logoImage: "ic_team_yellow_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_red_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_purple_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_blue_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_green_big", isImageSelected: false),
teamSelected(logoImage: "ic_team_orange_big", isImageSelected: false)
]
这是我的 collection 查看方法:
extension TeamViewController : UICollectionViewDelegate , UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return teamSelectionList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let teamSelection : TeamSelectionCollectionViewCell = self.teamCollectionView.dequeueReusableCell(withReuseIdentifier: "teamCell", for: indexPath) as! TeamSelectionCollectionViewCell
let row = teamSelectionList[indexPath.row]
teamSelection.logoImage.image = UIImage(named: row.logoImage)
teamSelection.logoButton.isSelected = row.isImageSelected
//teamSelection.logoButton.layer.setValue(row, forKey: "index")
teamSelection.logoButton.tag = indexPath.row
teamSelection.logoButton.addTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
teamSelection.seperatorView.isHidden = indexPath.row == 2 || indexPath.row == self.teamSelectionList.count - 1 ? true : false
return teamSelection
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: (teamCollectionView.frame.width / 3), height: 110.0)
}
@objc func logoButtonTapped(sender: UIButton){
// self.teamSelectionList[sender.tag].isImageSelected = true
// self.teamSelectionList[self.currentIndex].isImageSelected = self.currentIndex != sender.tag ? false : true
self.currentIndex = sender.tag
if (teamSelectionList[self.currentIndex].isImageSelected == false){
teamSelectionList[self.currentIndex].isImageSelected = true
sender.setImage(UIImage(named: "ic_radio_selected"), for: UIControl.State.normal)
} else {
teamSelectionList[self.currentIndex].isImageSelected = false
sender.setImage(UIImage(named: "ic_radio_normal"), for: UIControl.State.normal)
}
self.teamCollectionView.reloadData()
}
}
这是我得到的输出:
您在点击后使用 sender.setImage
更新选择图像。集合视图重复使用单元格,不能保证在下一个布局中使用相同的单元格。
我建议您将其从 logoButtonTapped
移至 cellForItemAt
,例如:
teamSelection.logoButton.isSelected = row.isImageSelected
teamSelection.logoButton.setImage(
UIImage(named: row.isImageSelected ? "ic_radio_normal" : "ic_radio_selected"),
for: UIControl.State.normal
)
还有一些提示。
- 根据 swift 代码风格指南,类 和结构的名称以大写字母开头并使用驼峰式大小写,例如
struct TeamSelected
而不是struct teamSelected
。当您了解您是在调用函数还是 class/struct 构造函数时,阅读起来会容易得多。 - 存储选定的索引比存储每个项目的选择状态要容易得多。它需要更少的代码并降低错误概率。您的代码可以这样更新:
class TeamViewController: UIViewController {
let teamLogoList = [
"ic_team_yellow_big",
"ic_team_red_big",
"ic_team_purple_big",
"ic_team_blue_big",
"ic_team_green_big",
"ic_team_orange_big",
]
var selection = Set<Int>()
}
extension TeamViewController : UICollectionViewDelegate , UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return teamLogoList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let teamSelection : TeamSelectionCollectionViewCell = self.teamCollectionView.dequeueReusableCell(withReuseIdentifier: "teamCell", for: indexPath) as! TeamSelectionCollectionViewCell
let index = indexPath.row
teamSelection.logoImage.image = UIImage(named: teamLogoList[index])
let isImageSelected = selection.contains(index)
teamSelection.logoButton.isSelected = isImageSelected
teamSelection.logoButton.setImage(
UIImage(named: isImageSelected ? "ic_radio_normal" : "ic_radio_selected"),
for: UIControl.State.normal
)
//teamSelection.logoButton.layer.setValue(row, forKey: "index")
teamSelection.logoButton.tag = indexPath.row
teamSelection.logoButton.addTarget(self, action: #selector(logoButtonTapped), for: .touchUpInside)
teamSelection.seperatorView.isHidden = indexPath.row == 2 || indexPath.row == self.teamLogoList.count - 1 ? true : false
return teamSelection
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: (teamCollectionView.frame.width / 3), height: 110.0)
}
@objc func logoButtonTapped(sender: UIButton){
let index = sender.tag
if (selection.contains(index)){
selection.remove(index)
} else {
selection.insert(index)
}
self.teamCollectionView.reloadData()
}
}