Sunteți pe pagina 1din 14

//

// CommentCollectionView.swift

import UIKit
import RealmSwift

class CommentTableView : UITableView , UITableViewDataSource , UITableViewDelegate {

// MARK: - Variables
var comments : Results<PublicationComment>? {
didSet {
reloadData()
}
}
//
let cellId = "cellId"
var searchDelegate : SearchResultSize?
//
var isSearChing = false
var searchKey = "" {
didSet {
if StringUtils.isStringEmpty(str: searchKey) {
comments = PublicationCommentDAO.getAll(by: (publicationId))
} else {
let predicate = NSPredicate(format: "comment CONTAINS[cd] %@", searchKey)
comments = PublicationCommentDAO.getAll(by: (publicationId))?.filter(predicate)
}
registerForRealmNotification()
}
}

override init(frame: CGRect, style: UITableViewStyle) {


super.init(frame: frame, style: style)

self.delegate = self
self.dataSource = self

self.translatesAutoresizingMaskIntoConstraints = false
backgroundColor = ColorConstant.lighGrayBackground
self.separatorStyle = .none
self.showsVerticalScrollIndicator = false
self.register(CommentCell.self, forCellReuseIdentifier: cellId)
}

// MARK: - Init Data source


var publicationId = "" {
didSet {
comments = PublicationCommentDAO.getAll(by: (publicationId))
registerForRealmNotification()
if let owner = PublicationDAO.getBy(id: publicationId)?.owner {
publicationOwner = owner.idUser
}
}
}
//
var publicationOwner = ""
var isCellEditing = false
//
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Number of sections


func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

// MARK: - Number of items


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let comments = comments else {
return 0
}
return comments.count
}

// MARK: - Cell At IndexPath


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {

guard let comments = comments else {


return UITableViewCell()
}
let cell = dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CommentCell
cell.publicationOwner = publicationOwner
cell.comment = comments[indexPath.item]

return cell
}

// MARK: - Size item


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) ->
CGFloat {
//
let defaultHeight : CGFloat = 100.0
//
if let text = comments?[indexPath.item].comment {
let text = text
let font = LabelStyle.body.font
let estimatedHeight = text.height(withConstrainedWidth: frame.width - 16 - 32 - 16 -
16, font: font)

let height = estimatedHeight < 42 ? defaultHeight : defaultHeight + (estimatedHeight -


42)

return height
}
return defaultHeight
}

// MARK: Item space


func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) ->
CGFloat {
return 0.0
}

// MARK: - Table delegate


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

guard let comment = comments?[indexPath.item] else {


return
}

if comment.creatorComment?.idUser == ServiceBaseUrl.currentUser.id {
let action = UIAlertController(title: "Voulez vous :", message: "", preferredStyle:
.actionSheet)

let delete = UIAlertAction(title: "Supprimer", style: .default) { (deleteAction) in


PublicationCommentsService.delete(idComment: comment.idComment,
idPublication: comment.idPublication)
PublicationCommentDAO.delete(using: comment.idComment)
}

let update = UIAlertAction(title: "Modifier", style: .default) { (updateAction) in


let cell = self.cellForRow(at: indexPath) as! CommentCell
cell.isCellEditing = true
}
//
let copy = UIAlertAction(title: "Copier", style: .default) { (updateAction) in
UIPasteboard.general.string = comment.comment
}
//
let cancel = UIAlertAction(title: "Annuler", style: .cancel, handler: nil)

action.addAction(copy)
action.addAction(delete)
action.addAction(update)
action.addAction(cancel)

NavigationManager.shared.present(viewController: action, animated: true)

} else {
//
let action = UIAlertController(title: "Voulez vous !", message: "", preferredStyle:
.actionSheet)
//
let report = UIAlertAction(title: "Signaler", style: .default) { (deleteAction) in

}
//
let cancel = UIAlertAction(title: "Annuler", style: .cancel, handler: nil)
//
let copy = UIAlertAction(title: "Copier", style: .default) { (updateAction) in
UIPasteboard.general.string = comment.comment
}
//
if publicationOwner == ServiceBaseUrl.currentUser.id {

let delete = UIAlertAction(title: "Supprimer", style: .default) { (deleteAction) in


PublicationCommentsService.delete(idComment: comment.idComment,
idPublication: comment.idPublication)
PublicationCommentDAO.delete(using: comment.idComment)
}
let block = UIAlertAction(title: "bloquer", style: .default) { (deleteAction) in
PublicationCommentsService.delete(idComment: comment.idComment,
idPublication: comment.idPublication)
PublicationCommentDAO.delete(using: comment.idComment)
// block the user logic

}
action.addAction(delete)
action.addAction(block)
}
//
action.addAction(report)
action.addAction(copy)
action.addAction(cancel)
//
NavigationManager.shared.present(viewController: action, animated: true)
}
}

// MARK: - RealmNotification
var commentResultNotificationToken: NotificationToken? = nil
//

// MARK: - RealmNotification
func registerForRealmNotification(){
commentResultNotificationToken = comments?.addNotificationBlock { [weak self]
(changes: RealmCollectionChange) in

guard let tableView = self else { return }


if tableView.isSearChing {
if let comments = tableView.comments {
tableView.searchDelegate?.did(get: comments.count)
}
}
switch changes {
case .initial:
// Results are now populated and can be accessed without blocking the UI
tableView.reloadData()
break
case .update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
tableView.beginUpdates()
tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
with: .fade)
tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.endUpdates()

break
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
break
}
}

//
deinit {
commentResultNotificationToken?.stop()
}

//
func deregisterFromRealmNotification() {
commentResultNotificationToken?.stop()
}

// MARK: - Load more and pull to refresh function


func refresh(_ refreshControl: UIRefreshControl) {
if StringUtils.isStringEmpty(str: publicationId) {
return
}
//
PublicationCommentsService.loadMore(for: publicationId)
refreshControl.endRefreshing()
}

//
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate:
Bool) {

//Bottom Refresh

if scrollView == self {

if ((scrollView.contentOffset.y + scrollView.frame.size.height) >=


scrollView.contentSize.height){

if isSearChing && !StringUtils.isStringEmpty(str: searchKey) {

PublicationCommentsService.loadMore(for: publicationId, searchKey:


searchKey)

} else {

PublicationCommentsService.loadMore(for: publicationId)
}
}
}
}
}

//
// CommentListViewController.swift
//
//

import UIKit
import RealmSwift

protocol SearchResultSize {
func did(get number : Int)
}

class CommentListViewController: BaseViewController , UITextFieldDelegate ,


UISearchBarDelegate , SearchResultSize{

var activeField: UITextField?


var bottomInputConstrain : NSLayoutConstraint?
var isAdding = false
//
var isSearching = false {
didSet {
commentTableView.isSearChing = isSearching
//
if oldValue == isSearching { return }
if isSearching {
showSearchResult()
} else {
hideSearchResult()
}
}
}
//
var publicationId = "" {
didSet {
commentTableView.publicationId = publicationId
}
}
//
lazy var searchBar : UISearchBar = {
let searchBar = UISearchBar()
searchBar.barStyle = .blackOpaque
searchBar.translatesAutoresizingMaskIntoConstraints = false
searchBar.delegate = self
searchBar.placeholder = "Rechercher"
searchBar.backgroundImage = UIImage()
let tf = searchBar.value(forKey: "_searchField") as? UITextField
tf?.backgroundColor = .clear
tf?.withAppShadow()
tf?.textColor = .black
tf?.font = LabelStyle.body.font
searchBar.showsCancelButton = false
searchBar.backgroundColor = .white
searchBar.addLargeShadow()
return searchBar
}()
//

//
lazy var cancelSearchButton: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setImage(#imageLiteral(resourceName: "ic_video_close"), for: .normal)
btn.isHidden = true
btn.addTarget(self, action: #selector(cancelSearch), for: .touchUpInside)
return btn
}()
//
let commentTableView : CommentTableView = {
let tableView = CommentTableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.withAppShadow()
tableView.layer.cornerRadius = 5.0
return tableView
}()

let collectionViewShadowHolder : UIView = {

let view = UIView(frame: .zero)


view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .clear
view.withAppShadow()
return view
}()

let result : SearchResultView = {

let view = SearchResultView(frame: .zero)


view.translatesAutoresizingMaskIntoConstraints = false
view.isHidden = true
return view
}()

lazy var inputViewHolder : InputViewHolder = {

let inputTextHolder = InputViewHolder(frame: .zero)


inputTextHolder.translatesAutoresizingMaskIntoConstraints = false
inputTextHolder.textView.delegate = self
return inputTextHolder
}()

// MARK: - Variables
//
override func viewDidLoad() {

super.viewDidLoad()
//
let cancelButtonAttributes: NSDictionary = [NSForegroundColorAttributeName:
ColorConstant.yellowAppColor]
UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes as? [String
: AnyObject], for: .normal)
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title =
"Annuler"
//
setupViews()
commentTableView.searchDelegate = self
}

override func viewDidAppear(_ animated: Bool) {


super.viewDidAppear(animated)
registerForKeyboardNotifications()
addTargetToCommentButton()
commentTableView.registerForRealmNotification()
if isAdding {
self.inputViewHolder.textView.becomeFirstResponder()

override func viewDidDisappear(_ animated: Bool) {


super.viewDidDisappear(animated)
deregisterFromKeyboardNotifications()
commentTableView.deregisterFromRealmNotification()
}
deinit {
commentTableView.deregisterFromRealmNotification()
}

func setupViews(){

view.backgroundColor = ColorConstant.lighGrayBackground

view.addSubview(inputViewHolder)
inputViewHolder.heightAnchor.constraint(equalToConstant: 50).isActive = true
inputViewHolder.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive =
true
inputViewHolder.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
bottomInputConstrain = inputViewHolder.bottomAnchor.constraint(equalTo:
view.bottomAnchor)
bottomInputConstrain?.isActive = true

view.addSubview(collectionViewShadowHolder)
collectionViewShadowHolder.topAnchor.constraint(equalTo: view.topAnchor, constant :
16).isActive = true
collectionViewShadowHolder.bottomAnchor.constraint(equalTo:
inputViewHolder.topAnchor , constant : -8).isActive = true
collectionViewShadowHolder.widthAnchor.constraint(equalTo: view.widthAnchor,
constant : -16).isActive = true
collectionViewShadowHolder.centerXAnchor.constraint(equalTo:
view.centerXAnchor).isActive = true

view.addSubview(searchBar)
searchBar.topAnchor.constraint(equalTo: view.topAnchor, constant : 16).isActive = true
searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
searchBar.widthAnchor.constraint(equalTo: view.widthAnchor, constant : -16).isActive =
true
searchBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
//
view.addSubview(commentTableView)
commentTableView.topAnchor.constraint(equalTo: searchBar.bottomAnchor, constant :
20).isActive = true
commentTableView.bottomAnchor.constraint(equalTo: inputViewHolder.topAnchor ,
constant : -8).isActive = true
commentTableView.widthAnchor.constraint(equalTo: view.widthAnchor, constant :
-16).isActive = true
commentTableView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive =
true

view.addSubview(result)
result.topAnchor.constraint(equalTo: searchBar.bottomAnchor, constant : 4).isActive =
true
result.heightAnchor.constraint(equalToConstant: 20).isActive = true
result.widthAnchor.constraint(equalTo: commentTableView.widthAnchor).isActive = true
result.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

}
func registerForKeyboardNotifications(){

// Adding notifies on keyboard appearing


NotificationCenter.default
.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name:
NSNotification.Name.UIKeyboardWillShow, object: nil)

NotificationCenter.default
.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name:
NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func deregisterFromKeyboardNotifications(){

// Removing notifies on keyboard appearing


NotificationCenter.default
.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)

NotificationCenter.default
.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func keyboardWasShown(notification: NSNotification){

let info = notification.userInfo!


let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as!
NSValue).cgRectValue

UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 1,


initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.bottomInputConstrain?.constant = -keyboardFrame.size.height
})

func keyboardWillBeHidden(notification: NSNotification){

UIView.animate(withDuration: 0.1, delay: 0, usingSpringWithDamping: 1,


initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.bottomInputConstrain?.constant = 0
})

func textFieldShouldReturn(_ textField: UITextField) -> Bool {


view.endEditing(true)
return true
}

//
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
self.inputViewHolder.isUserInteractionEnabled = true

if let text = searchBar.text {


if text != "" {
commentTableView.searchKey = text
isSearching = true
PublicationCommentsService.load(for: publicationId, searchKey: text)
debugPrint(text)
} else {
cancelSearch()
}
}
}
//
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = true

self.inputViewHolder.isUserInteractionEnabled = false
cancelSearchButton.fadeIn()
}
//
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
view.endEditing(true)
}
//
override func handleBackBtnAction(sender: UIBarButtonItem) {
if !self.inputViewHolder.isUserInteractionEnabled {
return
}
super.handleBackBtnAction(sender: sender)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
cancelSearch()
}
func cancelSearch() {
cancelSearchButton.fadeOut()
if !StringUtils.isStringEmpty(str: searchBar.text) {
PublicationCommentsService.load(for: publicationId)
}
searchBar.text = ""
view.endEditing(true)
//
commentTableView.searchKey = ""
isSearching = false
}

// MARK: - View animations


func showSearchResult(){
result.key = searchBar.text!
result.fadeIn()
}
//
func hideSearchResult(){
result.fadeOut()
result.key = ""
}

func did(get number : Int){


result.count = number
}
}
//
// CommentListVC+Mentions.swift
// BeeTheMove
//
// Created by Aymen Chouirfi on 5/31/17.
// Copyright © 2017 Symane. All rights reserved.
//

import UIKit

extension CommentListViewController : UITextViewDelegate {

// MARK: - TextView Delegates


func textViewDidBeginEditing(_ textView: UITextView) {

if textView.textColor == UIColor.lightGray {
textView.text = nil
textView.textColor = UIColor.black
}
}

func textViewDidEndEditing(_ textView: UITextView) {

if textView.text.isEmpty {
textView.text = " Votre commentaire..."
textView.textColor = UIColor.lightGray
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange,


replacementText text: String) -> Bool {

if text == "\n" {

textView.resignFirstResponder()
return false
}

if text == "@" {

Timer.scheduledTimer(withTimeInterval: 0.4, repeats: false, block: { (timer) in

let mentionVC = MentionBeesViewController()


mentionVC.refTextView = self.inputViewHolder.textView
let navController = UINavigationController(rootViewController: mentionVC)
self.present(navController, animated: true , completion: nil)
})
}

return true
}
}
https://stackoverflow.com/questions/4754392/uiview-with-rounded-corners-and-drop-shadow

S-ar putea să vă placă și