Last active
July 27, 2017 03:23
-
-
Save nazmulkp/761cfb16308891d998a163059c26bd55 to your computer and use it in GitHub Desktop.
The initial feed will download with 4 post for previewing, but if the user scrolling down then load more posts, so i need to add section to the bottom table view and section remove from the top.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
//import XCGLogger | |
typealias CheckResult = (Bool)->() | |
class NewsViewController: BaseViewController { | |
let newsfeedCellId = "newsfeedCellId" | |
// inject object dependency | |
lazy var apiClient: APINewsFeedsProtocol = APINewsFeedWebClient() | |
var tableViewIndex : IndexPath? | |
var states : [[State]]? | |
// variable to save the last position visited, default to zero | |
fileprivate var lastContentOffset: CGFloat = 0 | |
//variable to save the section added from top | |
var sectionFromTop : Int? | |
//variable to save the section added from bottom | |
var sectionFromBottom : Int? | |
var newestStateTime : Date? | |
var oldestStateTime : Date? | |
var searchBar : LeftAlignedSearchBar! | |
override func viewDidLoad() { | |
self.registerViews() | |
self.setupViews() | |
self.loadDataToTheView() | |
states = [[State]]() | |
initUpdateUI(createdAfter: nil, createdBefore: nil, completion: nil) | |
} | |
lazy var newsFeedTableView : UITableView = { | |
var tableView = UITableView() | |
tableView.backgroundColor = UIColor.white | |
tableView.dataSource = self | |
tableView.separatorStyle = .none | |
tableView.delegate = self | |
tableView.translatesAutoresizingMaskIntoConstraints = false | |
return tableView | |
}() | |
} | |
extension NewsViewController { | |
override func setupViews() { | |
self.view.addSubview(newsFeedTableView) | |
self.newsFeedTableView.fillSuperview()//rander the full screen | |
} | |
override func registerViews() { | |
newsFeedTableView.register(NewsTableViewViewCell.self, forCellReuseIdentifier: newsfeedCellId) | |
} | |
} | |
extension NewsViewController : UITableViewDataSource{ | |
func numberOfSections(in tableView: UITableView) -> Int { | |
return states?.count ?? 0 | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return states?[section].count ?? 0 | |
} | |
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { | |
let _states = self.states?[indexPath.section] | |
let _state = _states?[indexPath.row] | |
//let's get an estimation of the height of our cell based on user.bioText | |
let approximateWidthOfStateTextView = view.frame.width - 10 | |
return 250 + (_state?.text.height(withConstrainedWidth: approximateWidthOfStateTextView, font: UIFont(name: Constants.FontNames.SFNSText.SFNSTextRegular, size: 14)!))! | |
} | |
func scrollViewDidScroll(_ scrollView: UIScrollView) { | |
guard let indexpath = tableViewIndex else { return } | |
if self.lastContentOffset > scrollView.contentOffset.y { | |
if let _states = states?[indexpath.section]{ | |
if _states.count / 2 == indexpath.row + 1 { | |
if sectionFromTop != indexpath.section { | |
sectionFromTop = indexpath.section | |
self.newestState(createdAfter: _states.first?.createdAt, completion: nil) | |
} | |
} | |
} | |
} else if self.lastContentOffset < scrollView.contentOffset.y { | |
if let _states = states?[indexpath.section]{ | |
if _states.count / 2 == indexpath.row + 1 { | |
if sectionFromBottom != indexpath.section { | |
sectionFromBottom = indexpath.section | |
self.oldestState(createdBefore: _states.last?.createdAt, completion: nil) | |
} | |
} | |
} | |
} | |
self.lastContentOffset = scrollView.contentOffset.y | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: newsfeedCellId, for: indexPath) as! NewsTableViewViewCell | |
if let _states = states?[indexPath.section]{ | |
tableViewIndex = indexPath | |
cell.state = _states[indexPath.row] | |
cell.backgroundColor = UIColor.blue | |
} | |
return cell | |
} | |
} | |
extension NewsViewController : UITableViewDelegate { | |
} | |
//MARK:- Load Data to the UI | |
extension NewsViewController { | |
func initUpdateUI(createdAfter: Date?, createdBefore: Date?, completion: CheckResult?){ | |
self.loadNewsFeeds(createdAfter: nil, createdBefore: nil, completion: {(states) in | |
if let sortedStates = states { | |
self.states?.append(sortedStates) //Update states property | |
self.newestStateTime = sortedStates.first?.createdAt | |
self.oldestStateTime = sortedStates.last?.createdAt | |
DispatchQueue.main.async{ | |
self.newsFeedTableView.reloadData() | |
completion?(true) | |
} | |
} | |
} ) | |
} | |
func newestState(createdAfter createdAt: Date?, completion : CheckResult?){ | |
self.loadNewsFeeds(createdAfter: createdAt, createdBefore: nil, completion: {(states) in | |
if let sortedStates = states { | |
guard let firstCreatedAt = sortedStates.first?.createdAt else { | |
completion?(false) | |
return | |
} | |
guard let _newestStateTime = self.newestStateTime , _newestStateTime < firstCreatedAt else { | |
completion?(false) | |
return | |
} | |
self.newestStateTime = firstCreatedAt | |
self.states?.appendAtBeginning(newItem: sortedStates) | |
self.newsFeedTableView.insertSections([(self.states?.count)! - 3], with: UITableViewRowAnimation.none) | |
if (self.states?.count)! > 3 { | |
self.states?.removeLast() | |
let statesForoldestStateTime = self.states?.last | |
self.oldestStateTime = statesForoldestStateTime?.last?.createdAt | |
self.newsFeedTableView.deleteSections([(self.states?.count)! - 1], with: UITableViewRowAnimation.none) | |
} | |
completion?(true) | |
return | |
} | |
} ) | |
} | |
func oldestState(createdBefore createdAt: Date?, completion : CheckResult? ){ | |
self.loadNewsFeeds(createdAfter: nil, createdBefore: createdAt, completion: {(states) in | |
if let sortedStates = states { | |
guard let lastCreatedAt = sortedStates.last?.createdAt else { | |
completion?(false) | |
return | |
} | |
guard let _oldestStateTime = self.oldestStateTime , _oldestStateTime > lastCreatedAt else { | |
completion?(false) | |
return | |
} | |
self.oldestStateTime = lastCreatedAt | |
self.states?.append(sortedStates) //Update state property | |
self.newsFeedTableView.insertSections([(self.states?.count)! - 1], with: .none) | |
if (self.states?.count)! > 3 { | |
self.states?.removeFirst() | |
let statesForoldestStateTime = self.states?.first | |
self.newestStateTime = statesForoldestStateTime?.first?.createdAt | |
let indexpostion = (self.states?.count)! - 3 | |
self.newsFeedTableView.deleteSections([indexpostion], with: UITableViewRowAnimation.none) | |
} | |
completion?(true) | |
return | |
} | |
} ) | |
} | |
private func loadNewsFeeds(createdAfter: Date?, createdBefore: Date?, completion: @escaping ([State]?) | |
-> ()) { | |
var friendScopeId : UUID? | |
for (key , value) in (Global.account?.scopesDict)!{ | |
if key == "friends" { friendScopeId = value.id } | |
} | |
guard let _friendScopeId = friendScopeId else { return } | |
let statesByScope = StatesByScope(scopeId: String(describing: _friendScopeId), start: 0, limit: 0, createdAfter: createdAfter, createdBefore: createdBefore) | |
apiClient.loadNewsFeeds(forScope: statesByScope, completion: {(states, serviceError) in | |
if let error = serviceError { | |
print(error.localizedDescription) //Handle service error | |
} else if let _states = states { | |
let sortedStates = _states.sorted(by: {$0.createdAt! > $1.createdAt!}) | |
completion(sortedStates) | |
} | |
} ) | |
} | |
} | |
class NewsTableViewViewCell : BaseTableViewCell{ | |
var state : State?{ | |
didSet{ | |
statesTextView.text = state?.text | |
} | |
} | |
lazy var statesTextView: UITextView = { | |
let textView = UITextView() | |
textView.translatesAutoresizingMaskIntoConstraints = false | |
return textView | |
}() | |
override func setupViews() { | |
super.setupViews() | |
addSubview(statesTextView) | |
statesTextView.anchor(self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, topConstant: 5, leftConstant: 10, bottomConstant: 2, rightConstant: 5, widthConstant: 0, heightConstant: 0) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment