What is the best method or technique to use UIPageViewController

51 Views Asked by At

import Foundation
import UIKit

class HomeVC: UIViewController {
    
    //MARK: - Outlet
    
    @IBOutlet weak var tblView: UITableView!
    //------------------------------------------------------
    
    //MARK: - Class Variable
    private var viewModel : HomeVM = HomeVM()
    var currentPage = 1
    let refreshControl = UIRefreshControl()
    let reachability = try! Reachability()
    //------------------------------------------------------
    
    //MARK: - Memory Management Method
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
        
    deinit {
        debugPrint("‼️‼️‼️ deinit : \(self.classForCoder) ‼️‼️‼️")
    }
    
    //------------------------------------------------------
    
    //MARK: - Life Cycle Method
    
    override func viewDidLoad() {
        super.viewDidLoad()
//        setUpView()
    }

    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setUpView()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    }
    //------------------------------------------------------
              
    //MARK: - Custom Method
    
    private func setUpView() {
        self.applyStyle()
        self.setupViewModelObserver()
        self.viewModel.apiCallHome(page: currentPage)
        self.showToast(message: "Page \(currentPage)", font: .systemFont(ofSize: 17.0))
    }
    
    private func applyStyle(){
        self.tblView.separatorStyle = .none
        
        refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
        refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
        tblView.addSubview(refreshControl)
    }
    @objc func refresh(_ sender: AnyObject) {
       // Code to refresh table view
        self.currentPage = 1
        self.viewModel.apiCallHome(page: currentPage)
        self.showToast(message: "Page \(currentPage)", font: .systemFont(ofSize: 17.0))
        self.refreshControl.endRefreshing()
    }
    /**
     Setup all view model observer and handel data and erros.
     */
    private func setupViewModelObserver() {
        viewModel.eventHandler = { events in
            switch events {
            case .startLoading:
                debugPrint("Start_Loading")
            case .stopLoading:
                debugPrint("Stop_Loading")
            case .dataLoaded:
                DispatchQueue.main.async {
                    self.tblView.reloadData()
                }
            case .message( let error):
                debugPrint(error as Any)
            }
        }
    }
    
    //------------------------------------------------------
       
    //MARK: - Action Method
      
    //------------------------------------------------------
    
}

//MARK: - UITableViewDelegate and DataSource Methods -
extension HomeVC: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.viewModel.arrHomeData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTblCell", for: indexPath) as! HomeTblCell
        let data = self.viewModel.arrHomeData[indexPath.row]
        cell.imgAvatar.setImage(with: data.avatar ?? "")
        cell.lblFname.text = data.firstName
        cell.lblLName.text = data.lastName
        indexPath.row % 2 == 0 ? (cell.vwContainer.backgroundColor = UIColor.systemGray6) : (cell.vwContainer.backgroundColor = UIColor.systemGray3)
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "PageVC") as! PageVC
        let data = self.viewModel.arrHomeData[indexPath.row]
        vc.imageName = data.avatar
        vc.fName = data.firstName
        vc.lName = data.lastName
        vc.email = data.email
        self.navigationController?.pushViewController(vc, animated: true)
    }
                
//    func scrollViewDidScroll(_ scrollView: UIScrollView) {
//            let height = scrollView.frame.size.height
//            let contentYoffset = scrollView.contentOffset.y
//            let distanceFromBottom = scrollView.contentSize.height - contentYoffset
//            if distanceFromBottom < height {
//                print("you reached end of the table")
//                self.currentPage = 2
//                self.viewModel.apiCallHome(page: currentPage)
//                self.showToast(message: "Page \(currentPage)", font: .systemFont(ofSize: 17.0))
//            }
//    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let offset: CGPoint = scrollView.contentOffset
        let bounds: CGRect = scrollView.bounds
        let size: CGSize = scrollView.contentSize
        let inset: UIEdgeInsets = scrollView.contentInset
        let y: CGFloat = offset.y + bounds.size.height - inset.bottom
        let h: CGFloat = size.height
        //        print("offset: %f", offset.y)
        //        print("content.height: %f", size.height)
        //        print("bounds.height: %f", bounds.size.height)
        //        print("inset.top: %f", inset.top)
        //        print("inset.bottom: %f", inset.bottom)
        //        print("position: %f of %f", y, h)
        
        let reloadDistance: CGFloat = 30
        
        if (y > h + reloadDistance) {
            print("load more rows")
            self.currentPage = 2
            self.viewModel.apiCallHome(page: currentPage)
            self.showToast(message: "Page \(currentPage)", font: .systemFont(ofSize: 17.0))
        }
    }
      
    private func isLastCell(indexPath: IndexPath) -> Bool {
        print(indexPath)
        if self.viewModel.arrHomeData.count > 0 {
            return ((indexPath.section == indexPath.section-1) && (indexPath.row == (self.viewModel.arrHomeData.count-1)))
        } else {
            return false
        }
    }
}


extension UIViewController {

func showToast(message : String, font: UIFont) {
    let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 75, y: self.view.frame.size.height-100, width: 150, height: 35))
    toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    toastLabel.textColor = UIColor.white
    toastLabel.font = font
    toastLabel.textAlignment = .center
    toastLabel.text = message
    toastLabel.alpha = 1.0
    toastLabel.layer.cornerRadius = 10
    toastLabel.clipsToBounds  =  true
    self.view.addSubview(toastLabel)
    UIView.animate(withDuration: 4.0, delay: 0.1, options: .curveEaseOut, animations: {
         toastLabel.alpha = 0.0
    }, completion: {(isCompleted) in
        toastLabel.removeFromSuperview()
    })
} }

I have tried above methods, Is there any other methods to use UIPageViewController within a single ViewController. P.S :- I don't want to create separate class for UIPageViewController, I only want use it as above method, So If anyone know the Proper method to do this using this technique then please share.

1

There are 1 best solutions below

0
Duncan C On

Your question title asks about UIPageViewController, but the code you posted (almost 200 lines) does not include any reference to a UIPageViewController. Then you say "...I only want use it as above method..." What method is that, given that your code does not use a page view controller at all?

You can either use a page view controller as-is, or subclass it if desired. As DonMag references in the answer he links, you can include a page view controller's view as a child view of another view controller if desired.

That would be my recommendation: Create a customer view controller that includes a UIPageViewController as a child view. Have the parent view controller set up and manage the other views on the parent page, if any are needed. (The part that doesn't change when the user switches pages.) Also have the parent serve as the UIPageViewController's delegate.