FSCalendar - Paging nội dung theo ngày.
Bài đăng này đã không được cập nhật trong 3 năm
FSCalendar là gì?
FSCalendar là một thư viện lịch dành cho iOS có thể tuỳ chỉnh, làm việc tương thích với cả Objective-C và Swift.
Mọi người thể tìm hiểu thêm tại đây https://github.com/WenchaoD/FSCalendar
Một vài hình ảnh được chia sẻ từ FSCalendar
iPhone
iPad
Áp dụng Page View Controller cho FSCalendar.
Mục đích là có thể swipe sang trái, sang phải ở nội dung để có thể thay đổi nội dung theo ngày.
Sau đây mình sẽ hướng dẫn các bạn làm.
Các view controller
- DayModeViewController - Chứa calendar và pageViewController
- DayModePageViewController - Được kế thừa từ UIPageViewController, dùng để hiện thực nội dung cũng như bắt sự kiện swipe trái / phải.
- DayModeContentViewController - Chứa các events được filter theo từng ngày.
DayModeContentViewController
Trong ContentViewController, tạo 1 tableView để hiện thỉ nội dung. Như ví dụ ở đây chỉ tạo nội dung về events, các bạn có thể tuỳ biến việc nội dung hiện thị ra sao.
// MARK:- UITableViewDataSource
extension DayModeContentViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell.init(style: .subtitle, reuseIdentifier: nil)
cell.imageView?.image = UIImage(named: "icon_cat")
cell.textLabel?.text = "\(indexPath.row + 1)/ Lorem ipsum dolor sit er elit lamet"
if let date = date {
cell.detailTextLabel?.text = dateFormatter.string(from: date)
}
return cell
}
}
// MARK:- UITableViewDelegate
extension DayModeContentViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let date = date {
let label = UILabel()
label.text = " 📅 \(dateFormatter.string(from: date))"
label.textColor = .white
label.backgroundColor = .lightGray
return label
}
return nil
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
}
DayModePageViewController
Tại đây mình có tạo một protocol để bắt sự kiện swipe và callback nội dung về DayModeViewController
protocol DayModePageDelegate: NSObject {
func swipeDate(date: Date?)
func swipeNextDate(date: Date?)
func swipePreviousDate(date: Date?)
}
Trong DayModePageViewController sẽ kế thừa UIPageViewControllerDataSource
và UIPageViewControllerDelegate
extension DayModePageViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {
// Khởi tạo Content View Controller dựa vào date
func createContentViewController(_ date: Date) -> UIViewController {
let vc = DayModeContentVC()
vc.date = date
return vc
}
// Lấy View Controller đang hiện thị ở PageViewController
func getCurrentViewController() -> DayModeContentVC? {
return viewControllers?.first as? DayModeContentVC
}
// DataSource & Delegate - Khởi tạo Content của ngày hôm qua
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
return createContentViewController(self.previousDay)
}
// DataSource & Delegate - Khởi tạo Content của ngày kế tiếp
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
return createContentViewController(self.nextDay)
}
// DataSource & Delegate - Sự kiện sau khi swipe thành công, sẽ trả dữ liệu về trang DayModeViewController để xử lý các mong muốn.
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if finished, let delegate = dayModePageDelegate, let vc = getCurrentViewController() {
currentDate = vc.date ?? currentDate
delegate.swipeDate(date: vc.date)
}
}
}
DayModeViewController
Khởi tạo một số biến cần thiết.
var calendar: FSCalendar! //Tạo một calendar ở header
var containerView: UIView! //Chứa view của pageViewController
var pageViewController: DayModePageViewController!
Gắn pageViewController vào containerView
pageViewController = DayModePageViewController(selectedDay: calendar.selectedDate ?? Date())
pageViewController.dayModePageDelegate = self
addChildViewController(pageViewController)
containerView.addSubview(pageViewController.view)
pageViewController.didMove(toParentViewController: self)
Nhận sự kiện từ PageViewController thông qua delegate
// MARK:- DayModePageDelegate
extension DayModeViewController: DayModePageDelegate {
func swipeDate(date: Date?) {
calendar.select(date, scrollToDate: true)
}
func swipeNextDate(date: Date?) {
}
func swipePreviousDate(date: Date?) {
}
}
Kết quả
Ngoài ra các bạn có thể customize thêm nhiều thứ khác mà FSCalendar hỗ trợ.
Full SourceCode:
https://github.com/tranhanhuy/FSCalendar/tree/project/day-mode
Một vài hình ảnh:
All rights reserved