通过 UIButton 使用自定义 TableViewCell 添加到收藏夹并保存到 UserDefaults
Add to Favorite using Custom TableViewCell via UIButton & Save to UserDefaults
目标:在自定义 TableViewCell 中创建一个“添加到收藏夹”按钮,然后将收藏夹列表保存到 UserDefaults 中,这样我们就可以获得仅收藏夹的表格视图。 (我使用 segmentedControl 作为过滤方法 libraryFilter = 0
(Plan) / 1 = Tag / 2 = Duration / 3 = Favorite)
jsonErgWorkouts
是 JSON 文件中的锻炼数组,它是过滤的基础。
这是我编写的代码。
自定义 TableViewCell:
import UIKit
class ErgWorkoutCell: UITableViewCell {
@IBOutlet weak var ergWorkoutTitle: UILabel!
}
在 TableView 视图控制器中
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let selectedGroup = selectedWorkoutGroup(libraryFilter: libraryFilter, jsonErgWorkouts: jsonErgWorkouts, workoutGroupBox: workoutGroupBox)
/// this is cast AS! ErgWorkoutCell since this is a custom tableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "ergWorkoutCell") as! ErgWorkoutCell
cell.ergWorkoutTitle.text = selectedGroup[indexPath.row].title
return cell
}
}
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
if libraryFilter == 0 { // Segmented Control #1 (Plan)
selectedGroup = jsonErgWorkouts.filter { [=11=].group == workoutGroupBox.text }
/// code for libraryFilter 1(Tag)
/// and libraryFilter 2(Duration)
} else if libraryFilter == 3 {
// Need code here to return the filtered JSON of favorites only
}
return selectedGroup
}
需要做的事情很少。我还将 link 一些有助于实现此解决方案的 SO 页面。
- 在故事板中添加一个按钮
- 在自定义 TableViewCell 中添加按钮定义 (IBOutlet/IBAction) 和闭包
- 添加一种将所选收藏夹存储到 UserDefaults 的方法
- 在 segmentedControl 中显示收藏夹列表。
让我们开始吧:
在 Storyboard 中添加一个按钮
我会把这个留给用户
在自定义 TableViewCell 中添加按钮定义 (IBOutlet/IBAction) 和闭包
import UIKit
class ErgWorkoutCell: UITableViewCell {
@IBOutlet weak var ergWorkoutTitle: UILabel!
/// Create and Connect your Button outlet
@IBOutlet weak var ergWorkoutFavBtn: UIButton!
/// create your closure here
/// https://whosebug.com/a/55743790/14414215
var favButtonPressed : (() -> ()) = {}
/// Create & Connect an IBAction when your button is pressed.
@IBAction func ergWorkoutFavBtn(_ sender: UIButton) {
/// Call your closure here
favButtonPressed()
}
}
添加一种将所选收藏夹存储到 UserDefaults 的方法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/// https://whosebug.com/a/37357869/14414215
/// https://whosebug.com/q/65355061/14414215
/// Provide an initial default (empty array) to the UserDefaults Array since on startup there is no fav in the list.
var rowsWhichAreChecked = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int] ?? [Int]()
/// this is cast AS! ErgWorkoutCell since this is a custom tableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "ergWorkoutCell") as! ErgWorkoutCell
cell.ergWorkoutTitle.text = selectedGroup[indexPath.row].title
/// This is to change the image between favourited or Not
if rowsWhichAreChecked.contains(selectedGroup[indexPath.row].id) {
cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-full"), for: .normal)
} else {
cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-empty"), for: .normal)
}
/// https://whosebug.com/a/55743790/14414215
/// Once the FavButton is pressed, we determine if the selected item is already
/// in the FavList. If Yes, we remove it, if Not, we add it in.
/// We then reload the table
/// Added [ weak self] in based on @azehe
/// https://whosebug.com/q/64297651/14414215
cell.favButtonPressed = { [ weak self ] in
if rowsWhichAreChecked.contains(selectedGroup[indexPath.row].id) {
let removeIdx = rowsWhichAreChecked.lastIndex(where: {[=11=] == selectedGroup[indexPath.row].id})
rowsWhichAreChecked.remove(at: removeIdx!)
cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-empty"), for: .normal)
} else {
cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-full"), for: .normal)
rowsWhichAreChecked.append(selectedGroup[indexPath.row].id)
}
UserDefaults.standard.set(rowsWhichAreChecked, forKey: "workoutFavorite")
self?.vcLibTableView.reloadData() // self? instead of self (with [weak self] in
}
return cell
}
在分段控件中显示收藏夹列表。
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
/// https://whosebug.com/a/37357869/14414215
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int] ?? [Int]()
if libraryFilter == 0 {
selectedGroup = jsonErgWorkouts.filter { [=12=].group == workoutGroupBox.text }
} else if libraryFilter == 1 {
/// https://whosebug.com/q/65355061/14414215
selectedGroup = workoutFav.flatMap { favouriteId in // for each favourite ID
jsonErgWorkouts.filter { [=12=].id == favouriteId }
} // flatMap joins all those arrays returns by "filter" together, no need to do anything else
}
return selectedGroup
}
目标:在自定义 TableViewCell 中创建一个“添加到收藏夹”按钮,然后将收藏夹列表保存到 UserDefaults 中,这样我们就可以获得仅收藏夹的表格视图。 (我使用 segmentedControl 作为过滤方法 libraryFilter = 0
(Plan) / 1 = Tag / 2 = Duration / 3 = Favorite)
jsonErgWorkouts
是 JSON 文件中的锻炼数组,它是过滤的基础。
这是我编写的代码。
自定义 TableViewCell:
import UIKit
class ErgWorkoutCell: UITableViewCell {
@IBOutlet weak var ergWorkoutTitle: UILabel!
}
在 TableView 视图控制器中
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let selectedGroup = selectedWorkoutGroup(libraryFilter: libraryFilter, jsonErgWorkouts: jsonErgWorkouts, workoutGroupBox: workoutGroupBox)
/// this is cast AS! ErgWorkoutCell since this is a custom tableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "ergWorkoutCell") as! ErgWorkoutCell
cell.ergWorkoutTitle.text = selectedGroup[indexPath.row].title
return cell
}
}
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
if libraryFilter == 0 { // Segmented Control #1 (Plan)
selectedGroup = jsonErgWorkouts.filter { [=11=].group == workoutGroupBox.text }
/// code for libraryFilter 1(Tag)
/// and libraryFilter 2(Duration)
} else if libraryFilter == 3 {
// Need code here to return the filtered JSON of favorites only
}
return selectedGroup
}
需要做的事情很少。我还将 link 一些有助于实现此解决方案的 SO 页面。
- 在故事板中添加一个按钮
- 在自定义 TableViewCell 中添加按钮定义 (IBOutlet/IBAction) 和闭包
- 添加一种将所选收藏夹存储到 UserDefaults 的方法
- 在 segmentedControl 中显示收藏夹列表。
让我们开始吧:
在 Storyboard 中添加一个按钮
我会把这个留给用户
在自定义 TableViewCell 中添加按钮定义 (IBOutlet/IBAction) 和闭包
import UIKit class ErgWorkoutCell: UITableViewCell { @IBOutlet weak var ergWorkoutTitle: UILabel! /// Create and Connect your Button outlet @IBOutlet weak var ergWorkoutFavBtn: UIButton! /// create your closure here /// https://whosebug.com/a/55743790/14414215 var favButtonPressed : (() -> ()) = {} /// Create & Connect an IBAction when your button is pressed. @IBAction func ergWorkoutFavBtn(_ sender: UIButton) { /// Call your closure here favButtonPressed() } }
添加一种将所选收藏夹存储到 UserDefaults 的方法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { /// https://whosebug.com/a/37357869/14414215 /// https://whosebug.com/q/65355061/14414215 /// Provide an initial default (empty array) to the UserDefaults Array since on startup there is no fav in the list. var rowsWhichAreChecked = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int] ?? [Int]() /// this is cast AS! ErgWorkoutCell since this is a custom tableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: "ergWorkoutCell") as! ErgWorkoutCell cell.ergWorkoutTitle.text = selectedGroup[indexPath.row].title /// This is to change the image between favourited or Not if rowsWhichAreChecked.contains(selectedGroup[indexPath.row].id) { cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-full"), for: .normal) } else { cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-empty"), for: .normal) } /// https://whosebug.com/a/55743790/14414215 /// Once the FavButton is pressed, we determine if the selected item is already /// in the FavList. If Yes, we remove it, if Not, we add it in. /// We then reload the table /// Added [ weak self] in based on @azehe /// https://whosebug.com/q/64297651/14414215 cell.favButtonPressed = { [ weak self ] in if rowsWhichAreChecked.contains(selectedGroup[indexPath.row].id) { let removeIdx = rowsWhichAreChecked.lastIndex(where: {[=11=] == selectedGroup[indexPath.row].id}) rowsWhichAreChecked.remove(at: removeIdx!) cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-empty"), for: .normal) } else { cell.ergWorkoutFavBtn.setImage(#imageLiteral(resourceName: "star-full"), for: .normal) rowsWhichAreChecked.append(selectedGroup[indexPath.row].id) } UserDefaults.standard.set(rowsWhichAreChecked, forKey: "workoutFavorite") self?.vcLibTableView.reloadData() // self? instead of self (with [weak self] in } return cell }
在分段控件中显示收藏夹列表。
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
/// https://whosebug.com/a/37357869/14414215
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int] ?? [Int]()
if libraryFilter == 0 {
selectedGroup = jsonErgWorkouts.filter { [=12=].group == workoutGroupBox.text }
} else if libraryFilter == 1 {
/// https://whosebug.com/q/65355061/14414215
selectedGroup = workoutFav.flatMap { favouriteId in // for each favourite ID
jsonErgWorkouts.filter { [=12=].id == favouriteId }
} // flatMap joins all those arrays returns by "filter" together, no need to do anything else
}
return selectedGroup
}