#22 實作 Table View 的基本功能 -FB 頁面 part2

Lou
彼得潘的 Swift iOS / Flutter App 開發教室
14 min readJul 19, 2023
四個ViewController

HomePageTableViewController

排序貼文功能 viewWillAppear(在畫面出現之前)


override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 按照時間排序貼文
postArray.sort { (post1, post2) -> Bool in
return post1.timestamp > post2.timestamp
}
// 更新表格
tableView.reloadData()
}

自訂Navigation bar (加入menu按鈕)

Navigation bar分別左右兩邊區塊(加入menu按鈕)
    override func viewDidLoad() {
super.viewDidLoad()
setNavigationbar()
}

func setNavigationbar() {
// 設定左邊選單按鈕
let menuButton = UIButton(type: .system)
menuButton.frame = CGRect(x: 0, y: 0, width: 10, height: 40)
let leftBarSymbolConfig = UIImage.SymbolConfiguration(weight: .heavy)
let menuImage = UIImage(systemName: "line.3.horizontal", withConfiguration: leftBarSymbolConfig)
menuButton.setImage(menuImage, for: .normal)
menuButton.tintColor = UIColor(red: 5/255, green: 5/255, blue: 5/255, alpha: 1)
let barButtonItem = UIBarButtonItem(customView: menuButton)

// 設定標題
let label = UILabel()
label.text = "facebook"
label.textColor = UIColor(red: 23/255, green: 119/255, blue: 241/255, alpha: 1)
label.font = UIFont.boldSystemFont(ofSize: 30)
let labelItem = UIBarButtonItem(customView: label)

// 設定rightBarButtonItems的symbol圖片統一的樣式
let rightBarSymbolConfig = UIImage.SymbolConfiguration(weight: .heavy)
// 設定messageButton樣式
let messageButton = UIButton(type: .system)
messageButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let messageImage = UIImage(systemName: "message.fill", withConfiguration: rightBarSymbolConfig)
messageButton.setImage(messageImage, for: .normal)
messageButton.backgroundColor = UIColor(red: 228/255, green: 229/255, blue: 234/255, alpha: 1)
messageButton.tintColor = UIColor(red: 5/255, green: 5/255, blue: 5/255, alpha: 1)
messageButton.layer.cornerRadius = 20
let messageBarButtonItem = UIBarButtonItem(customView: messageButton)

// 設定searchButton樣式
let searchButton = UIButton(type: .system)
searchButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let searchImage = UIImage(systemName: "magnifyingglass", withConfiguration: rightBarSymbolConfig)
searchButton.setImage(searchImage, for: .normal)
searchButton.backgroundColor = UIColor(red: 228/255, green: 229/255, blue: 234/255, alpha: 1)
searchButton.tintColor = UIColor(red: 5/255, green: 5/255, blue: 5/255, alpha: 1)
searchButton.layer.cornerRadius = 20
let searchBarButtonItem = UIBarButtonItem(customView: searchButton)

// 設定plusButton樣式
let plusButton = UIButton(type: .system)
plusButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let plusImage = UIImage(systemName: "plus", withConfiguration: rightBarSymbolConfig)
plusButton.setImage(plusImage, for: .normal)
plusButton.backgroundColor = UIColor(red: 228/255, green: 229/255, blue: 234/255, alpha: 1)
plusButton.tintColor = UIColor(red: 5/255, green: 5/255, blue: 5/255, alpha: 1)
plusButton.layer.cornerRadius = 20
// 設定選單(menu)按鈕
plusButton.showsMenuAsPrimaryAction = true
plusButton.menu = UIMenu(children: [UIAction(title: "發佈",image: UIImage(systemName: "square.and.pencil") ,handler: { _ in
self.performSegue(withIdentifier: "showPostViewController", sender: self)
}),
UIAction(title: "限時動態",image: UIImage(systemName: "book.fill") ,handler: { _ in
print("限時動態")
}),
UIAction(title: "連續短片",image: UIImage(systemName: "play.rectangle.fill") ,handler: { _ in
print("連續短片")
}),
UIAction(title: "直播",image: UIImage(systemName: "video.fill") ,handler: { _ in
print("直播")
})
])
let plusBarButtonItem = UIBarButtonItem(customView: plusButton)


//加入按鈕樣式到Navugation
navigationItem.leftBarButtonItems = [barButtonItem, labelItem]
navigationItem.rightBarButtonItems = [messageBarButtonItem, searchBarButtonItem, plusBarButtonItem]
}

貼文按讚功能

按讚
    @IBAction func likePost(_ sender: UIButton) {

let point = sender.convert(CGPoint.zero, to: tableView) // 點選button的位置
if let indexPath = tableView.indexPathForRow(at: point){
let section = indexPath.section
let postSection = section - 2 // section第三個開始才是貼文
postArray[postSection].isLiked = !postArray[postSection].isLiked // 按讚 收回讚
let likeButtonImageName = postArray[postSection].likeButtonImageName
sender.setImage(UIImage(systemName: likeButtonImageName), for: .normal)

if postArray[postSection].isLiked {
sender.tintColor = UIColor(red: 23/255, green: 119/255, blue: 241/255, alpha: 1)
} else {
sender.tintColor = UIColor(red: 100/255, green: 103/255, blue: 106/255, alpha: 1)
}

// 取得likecountLabel所在的 indexPath
let postIndexPath = [IndexPath(row: 0, section: section)]
// 重新載入表格
tableView.reloadRows(at: postIndexPath, with: .none)

}
}

點選貼文cell功能(傳遞資料)

cell連結 SegueAction 查看內文

取得cell的section位置 傳遞到CommentViewController

    @IBSegueAction func showPost(_ coder: NSCoder) -> CommentViewController? {
guard let section = tableView.indexPathForSelectedRow?.section else { return nil }
let selectSection = section - 2
return CommentViewController(coder: coder, selectSection: selectSection, shouldOpenKeyboard: false)
}

點選留言按鈕功能(傳遞資料)

點選留言按鈕 進入內文留言 彈出鍵盤

commentButton Action取得按鈕的Section位置

    @IBAction func commentButtonTapped(_ sender: UIButton) {
self.selectedSection = sender.tag
}

commentButton SegueAction傳遞資料到CommentViewController

    @IBSegueAction func showPostComment(_ coder: NSCoder) -> CommentViewController? {
guard let section = self.selectedSection else { return nil }
let selectSection = section - 2
return CommentViewController(coder: coder, selectSection: selectSection, shouldOpenKeyboard: true)
}

照片點選功能

選取照片按鈕
選取照片功能
import PhotosUI

extension HomePageTableViewController: PHPickerViewControllerDelegate {

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)

guard !results.isEmpty else {
// 使用者沒有選擇照片
return
}

let itemProvider = results.first?.itemProvider

if let itemProvider = itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (object, error) in
DispatchQueue.main.async {
if let error = error {
print("Error loading image: \(error)")
return
}

if let image = object as? UIImage {
// 使用 Segue 跳轉 PostViewController傳遞圖片
self?.performSegue(withIdentifier: "selcetPhoto", sender: image)
}
}
}
}

}
}

傳遞選取照片資料到下一頁(func prepare()必須有Segue才會觸發)

設定segue identifier
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "selcetPhoto",
let postViewController = segue.destination as? PostViewController,
let image = sender as? UIImage {
postViewController.selectedImage = image
}

下篇介紹part3

參考資料

--

--