ToDo List
TableViewController.swift
import UIKit
extension TodoTableViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let txt = searchController.searchBar.text?.lowercased() else { return }
self.filteredList.specialList = self.list.specialList.filter{ $0.main.lowercased().contains(txt) }
self.filteredList.todoList = self.list.todoList.filter{
$0.main.lowercased().contains(txt) }
self.tableView.reloadData()
}
}
class TodoTableViewController: UITableViewController {
var list = ToDoInformation()
var filteredList = ToDoInformation()
var isFiltering: Bool {
let searchController = self.navigationItem.searchController
let isActive = searchController?.isActive ?? false
let isSearchBarHasText = searchController?.searchBar.text?.isEmpty == false
print(isActive && isSearchBarHasText)
return isActive && isSearchBarHasText
}
func setupSearchController() {
let searchController = UISearchController(searchResultsController: nil)
self.navigationItem.searchController = searchController
searchController.searchResultsUpdater = self
}
func setupTableView() {
self.tableView.delegate = self
self.tableView.dataSource = self
}
@IBOutlet var pullDownButton: UIButton!
@IBOutlet var newTextField: UITextField!
@IBOutlet var okButton: UIButton!
var option = Option.일반.rawValue
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: identifier.TodoTableViewCell.rawValue, bundle: nil)
tableView.register(nib, forCellReuseIdentifier: identifier.TodoTableViewCell.rawValue)
designPullDownButton(pullDownButton)
setupTableView()
setupSearchController()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return (section == 0) ? "즐겨찾기" : "일반"
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (section == 0) {
if (isFiltering) {
return filteredList.specialList.count
} else {
return list.specialList.count
}
}
else {
if (isFiltering) {
return filteredList.todoList.count
} else {
return list.todoList.count
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: identifier.TodoTableViewCell.rawValue) as! TodoTableViewCell
if (indexPath.section == 0 ) {
if (isFiltering) {
let row = filteredList.specialList[indexPath.row]
cell.designCell(row)
}
else {
let row = list.specialList[indexPath.row]
cell.designCell(row)
}
}
else if (indexPath.section == 1 ){
if (isFiltering) {
let row = filteredList.todoList[indexPath.row]
cell.designCell(row)
}
else {
let row = list.todoList[indexPath.row]
cell.designCell(row)
}
}
cell.doneCallBackMethod = { [weak self] in
if (indexPath.section == 0 && !((self?.list.specialList[indexPath.row].done)!) ) {
var tmp: ToDo = (self?.list.specialList[indexPath.row])!
self?.list.specialList.remove(at: indexPath.row)
tmp.done = true;
self?.list.specialList.insert(tmp, at: (self?.list.specialList.count)!)
}
else if (indexPath.section == 1 && !((self?.list.todoList[indexPath.row].done)!) ) {
var tmp: ToDo = (self?.list.todoList[indexPath.row])!
self?.list.todoList.remove(at: indexPath.row)
tmp.done = true;
self?.list.todoList.insert(tmp, at: (self?.list.todoList.count)!)
}
tableView.reloadData()
}
cell.specialCallBackMethod = { [weak self] in
if (indexPath.section == 0 && !((self?.list.specialList[indexPath.row].done)!)) {
var tmp: ToDo = (self?.list.specialList[indexPath.row])!
self?.list.specialList.remove(at: indexPath.row)
tmp.special = false;
self?.list.todoList.insert(tmp, at: 0)
}
else if (indexPath.section == 1 && !((self?.list.todoList[indexPath.row].done)!)) {
var tmp: ToDo = (self?.list.todoList[indexPath.row])!
self?.list.todoList.remove(at: indexPath.row)
tmp.special = true
self?.list.specialList.insert(tmp, at: 0)
}
tableView.reloadData()
}
return cell
}
func designPullDownButton(_ sender: UIButton) {
sender.setTitle(option, for: .normal)
let op1 = UIAction(title: Option.즐겨찾기.rawValue) { _ in
self.option = Option.즐겨찾기.rawValue
sender.setTitle(self.option, for: .normal)
}
let op2 = UIAction(title: Option.일반.rawValue) { _ in
self.option = Option.일반.rawValue
sender.setTitle(self.option, for: .normal)
}
let buttonMenu = UIMenu(title: "선택", children: [op1, op2])
sender.menu = buttonMenu
}
func checkTextField(_ sender: UITextField) -> Bool {
if let txt = sender.text {
if txt.count >= 1 {
return true
}
}
return false
}
func updateList() {
if (checkTextField(newTextField)) {
let txt = newTextField.text!
if option == Option.일반.rawValue {
list.todoList.insert(ToDo(done: false, main: txt, special: false), at: 0)
tableView.reloadData()
newTextField.text = ""
}
else if option == Option.즐겨찾기.rawValue {
list.specialList.insert(ToDo(done: false, main: txt, special: true), at: 0)
tableView.reloadData()
newTextField.text = ""
}
}
else {
let alert = UIAlertController(title: "텍스트가 올바르지 않습니다", message: "다시 써주세요", preferredStyle: .alert)
let ok = UIAlertAction(title: "확인", style: .default)
alert.addAction(ok)
present(alert, animated: true)
}
}
@IBAction func textfieldReturnTapped(_ sender: UITextField) {
updateList()
}
@IBAction func okButtonTapped(_ sender: UIButton) {
updateList()
view.endEditing(true)
}
}
TableViewCell.swift
import UIKit
class TodoTableViewCell: UITableViewCell {
var specialCallBackMethod: (() -> Void)?
var doneCallBackMethod: (() -> Void)?
@IBOutlet var doneButton: UIButton!
@IBOutlet var specialButton: UIButton!
@IBOutlet var todoTextView: UITextView!
func designCell(_ sender: ToDo) {
doneButton.setImage(UIImage(systemName: (sender.done)
? "checkmark.square.fill"
: "checkmark.square")
, for: .normal)
specialButton.setImage(UIImage(systemName: (sender.special)
? "star.fill"
: "star")
, for: .normal)
todoTextView.text = sender.main
}
@IBAction func specialButtonTapped(_ sender: UIButton) {
specialCallBackMethod?()
}
@IBAction func doneButtonTapped(_ sender: UIButton) {
doneCallBackMethod?()
}
}
Movie List
ViewController
import UIKit
class BookViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet var bookCollectionView: UICollectionView!
@IBOutlet var bookTableView: UITableView!
var data = MovieInfo().movie
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "요즘 인기 작품"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cell.BookTableViewCell.rawValue) as! BookTableViewCell
cell.designCell(data[indexPath.row])
cell.heartCallBackMethod = { [weak self] in
self?.data[indexPath.row].like.toggle()
self?.bookTableView.reloadData()
self?.bookCollectionView.reloadData()
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.filter { $0.like }.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.BookCollectionViewCell.rawValue, for: indexPath) as! BookCollectionViewCell
cell.designCell(data.filter { $0.like }[indexPath.row] )
cell.heartCallBackMethod = { [weak self] in
let title = self?.data.filter{ $0.like }[indexPath.row].title
for i in 0...(self?.data.count)! - 1 {
if title == self?.data[i].title {
self?.data[i].like.toggle()
}
}
self?.bookCollectionView.reloadData()
self?.bookTableView.reloadData()
self?.configureCollectionViewLayout()
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(withIdentifier: Cell.DetailViewController.rawValue) as! DetailViewController
vc.contents = data[indexPath.row]
let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = .fullScreen
present(nav, animated: true)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(withIdentifier: Cell.DetailViewController.rawValue) as! DetailViewController
vc.contents = data.filter{ $0.like }[indexPath.row]
let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = .fullScreen
present(nav, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: Cell.BookTableViewCell.rawValue, bundle: nil)
bookTableView.register(nib, forCellReuseIdentifier: Cell.BookTableViewCell.rawValue)
let nib2 = UINib(nibName: Cell.BookCollectionViewCell.rawValue, bundle: nil)
bookCollectionView.register(nib2, forCellWithReuseIdentifier: Cell.BookCollectionViewCell.rawValue)
bookCollectionView.dataSource = self
bookCollectionView.delegate = self
bookTableView.dataSource = self
bookTableView.delegate = self
configureCollectionViewLayout()
bookTableView.rowHeight = 150
}
func configureCollectionViewLayout() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 100, height : 150)
layout.sectionInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
bookCollectionView.collectionViewLayout = layout
}
}
TableViewCell
import UIKit
class BookTableViewCell: UITableViewCell {
var heartCallBackMethod: ( () -> Void )?
@IBOutlet var posterImageView: UIImageView!
@IBOutlet var titleLabel: UILabel!
@IBOutlet var heartButton: UIButton!
@IBOutlet var subLabel: UILabel!
func designCell(_ sender: Movie) {
posterImageView.image = UIImage(named: sender.title)
posterImageView.contentMode = .scaleAspectFit
titleLabel.text = sender.title
subLabel.text = "\(sender.releaseDate) | \(sender.rate)"
heartButton.setImage(UIImage(systemName: (sender.like) ? "heart.fill" : "heart"),
for: .normal)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
@IBAction func heartButtonTapped(_ sender: UIButton) {
heartCallBackMethod?()
}
}