Je suis un debutant a 100% dans la creation d'application native (en Swift 4) et j'avoue assez galerer sur comment acceder a des methode (et attribut) se trouvant dans d'autres fichier .swift
La manipulation des donnees une fois que j'y ai acces, ca va j'arrive a peu pres a faire ce que je souhaite.
Pour la petite histoire: J'ai integre un projet en cours (alors que je suis 100% debutant) et on m'a donne comme challenge de faire quelque petite modification sur l'application. Voila...
Donc je vais essayer d'expliquer le mieux possible mon soucis.
1) J'ai une classe DetailsNoPhotoCell qui herite de UITableViewCell contenant une @IBAction
Comme ceci:
class DetailsNoPhotoCell: UITableViewCell,CellConfiguraable,TagListViewDelegate {
...
@IBAction func mon_Action(_ sender: Any) {
if let description = questionDetail.description{
let description = description.mon_filtre
}
}
}
2) le @IBAction est correctement executer lorsque je clique sur mon bouton
3) J'ai une autre class AnswerCell qui herite de UITableViewCell comme ci:
class AnswerCell: UITableViewCell,CellConfiguraable {
...
}
4) DetailsNoPhotoCell: correspond a la question principale AnswerCell: correspondent aux responses
Voici le DetailsNoPhotoCell:
Voici les AnswerCell:
5) Ce que je n'arrive pas a faire (et ne sais pas du tout comment faire) c'est depuis DetailsNoPhotoCell acceder aux AnswerCell (notamment a l'attribut "description" ou encore au mainView.isHidden )
6) Pour info (je ne sais pas si ca peut etre utile), j'ai plusieurs controller dans mon projet dont QuestionDetailsViewController definit comme ceci:
class QuestionDetailsViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate,GrowingTextViewDelegate, UITableViewDelegate,UITableViewDataSource,QuestionDetailDelegate,GADBannerViewDelegate {
...
}
7) En faisant des test, j'arrive a acceder aux AnswerCell au moment de leur creation en bidouillant la methode tableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let questionDetail = self.viewModel.questionDetail.value
let cellType = identifyCellType(questionDetail: questionDetail, indexPath: indexPath)
print("Type \(cellType.0)")
let cell = tableView.dequeueReusableCell(withIdentifier: cellType.0, for: indexPath)
if let cell = cell as? CellConfiguraable{
switch cellType.1{
case 1:
cell.configure(questionDetail: questionDetail,delegate : self)
case 2:
cell.configure(answer: questionDetail.list.object(at: indexPath.row) as! Answer,delegate : self)
default:
cell.configure(reply: questionDetail.list.object(at: indexPath.row) as! Reply,delegate : self)
}
}
cell.selectionStyle = .none
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
if indexPath[0] != 0 { // on cible uniquement les reponse
cell.isHidden = true
}
return cell
}
Donc j'essaie d'explorer cette piste...
Le hic c'est que j'ai besoin d'aide pour comprendre ce que fais, pour savoir comment bien penser, la logique a avoir, etc..
Salut, j’ai pas assez d’element Pour répondre à 100% à ta question. On devra sûrement faire plusieurs allers retour.
C’est quoi Celltype ?
Je peux quand même dire que tu ne peux pas et que tu ne dois pas accéder à une cell depuis une autre cell. C’est le rôle du contrôleur (en MVC). Donc effectivement ce sera dans le cellForRow
Le controller que je crois devoir fixer mon attention est comme je te l'ai dis QuestionDetailsViewController (mais je n'en suis pas sur c'est pour ca que je te montre l'arborescence du projet).
Voici ce que contient QuestionDetailsViewController.swift:
//
// QuestionDetailsViewController.swift
// test
//
// Created by test on 08/10/2018.
// Copyright test. All rights reserved.
//
import UIKit
import GrowingTextView
import SDWebImage
import RxSwift
import RxCocoa
import RxGesture
import ObjectMapper
import GoogleMobileAds
class QuestionDetailsViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate,GrowingTextViewDelegate, UITableViewDelegate,UITableViewDataSource,QuestionDetailDelegate,GADBannerViewDelegate {
enum Typing{
case Answer
case Reply
}
@IBOutlet weak var bookmark_label: UILabel!
@IBOutlet weak var official_icon: UIImageView!
@IBOutlet weak var topView: UIView!
@IBOutlet weak var official_widthConstraint: NSLayoutConstraint!
@IBOutlet weak var sendButton: UIButton!
@IBOutlet weak var textView: GrowingTextView!
@IBOutlet weak var cameraButton: UIButton!
@IBOutlet weak var bookmark_button: UIButton!
@IBOutlet weak var date: UILabel!
@IBOutlet weak var userNickname: UILabel!
@IBOutlet weak var userAvatar: UIImageView!
@IBOutlet weak var textViewBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var txtFieldContainer: UIView!
@IBOutlet weak var textViewContainer: UIView!
var darkBackground : UIView!
var refreshControl : UIRefreshControl!
var currentlyTyping : Typing = .Answer
var question : Question!
var viewModel = QuestionDetailViewModel()
var disposeBag = DisposeBag()
var cellHeights: [IndexPath : CGFloat] = [:]
var monTest: String = "Hello World"
//Image attaching stuff
var image : UIImage!
var showImagePicker = false
var imageURL : URL!
//TextView annotation stuff
var endingEdit = false
var reply_target_id = 0
var reply_to_nickname = ""
var reply_answer_index : Int!
var reply_to_answer_id : Int!
var transition_id : Int?
var transition_type : Int?
var transition_scrollToIndex = -2
var question_id : Int!
var bannerView: GADBannerView!
var ad_isOn = false
var checkUpdate : CheckUpdate!
let san = "さん"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//Admob Banner
bannerView = GADBannerView(adSize: kGADAdSizeBanner)
//addBannerViewToView(bannerView)
bannerView.adUnitID = Consts.banner_id
bannerView.rootViewController = self
let request = GADRequest()
request.testDevices = ["96cce857b74abb2b3238d9f498b8c02c"]
bannerView.delegate = self
bannerView.load(request)
bookmark_button.setTitle(bookmark_button.titleLabel!.text!.localized, for: .normal)
//tableView
tableView.rx.willDisplayCell.subscribe(onNext:{cell,indexPath in
self.cellHeights[indexPath] = cell.frame.size.height
print("==> COMPTEUR:")
if(indexPath.section == 1 && indexPath.row == self.transition_scrollToIndex){
var frame = cell.frame
frame.origin.y = 0
let view = UIView.init(frame: frame)
cell.addSubview(view)
view.backgroundColor = UIColor.init(red: 255.0/255.0, green: 254.0/255.0, blue: 242.0/255.0, alpha: 1)
UIView.animate(withDuration: 2 ,animations: {
view.alpha = 0
}, completion: {finished in
self.transition_scrollToIndex = -2
view.removeFromSuperview()
})
}
}).disposed(by: disposeBag)
//while writing layer
self.darkBackground = UIView.init(frame: self.view.frame)
darkBackground.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)
self.view.insertSubview(darkBackground, belowSubview: self.txtFieldContainer)
darkBackground.isHidden = true
//cameraButton setup
self.cameraButton.addTarget(self, action: #selector(imageAction), for: .touchUpInside)
self.cameraButton.contentMode = .scaleAspectFill
//Growing TextView
if #available(iOS 11.0, *) {
textView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
//tap to dismiss
self.view.rx.tapGesture(configuration: { gestureRecognizer, delegate in
delegate.touchReceptionPolicy = .custom { event in
if event.1.view == self.textView{
return false
}
return true
}
}).when(.recognized).subscribe({ event in
self.view.endEditing(true)
}).disposed(by:disposeBag)
//tableview config
self.refreshControl = UIRefreshControl()
self.refreshControl?.addTarget(self, action: #selector(refresh), for: .valueChanged)
if #available(iOS 10.0, *) {
self.tableView.refreshControl = refreshControl
} else {
//Fallback on earlier versions
}
tableView.delegate = nil
tableView.dataSource = nil
self.tableView.estimatedRowHeight = 200
self.tableView.rowHeight = UITableView.automaticDimension
let footer = UIView()
footer.backgroundColor = UIColor.init(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0, alpha: 1)
tableView.tableFooterView = footer
tableView.backgroundColor = UIColor.init(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0, alpha: 1)
//register needed
tableView.register(UINib(nibName: "DetailsOnePhotoCell", bundle: nil), forCellReuseIdentifier: "DetailsOnePhotoCell")
tableView.register(UINib(nibName: "DetailsNoPhotoCell", bundle: nil), forCellReuseIdentifier: "DetailsNoPhotoCell")
tableView.register(UINib(nibName: "DetailsMultiPhotoCell", bundle: nil), forCellReuseIdentifier: "DetailsMultiPhotoCell")
tableView.register(UINib(nibName: "AnswerWithPhotoCell", bundle: nil), forCellReuseIdentifier: "AnswerWithPhotoCell")
tableView.register(UINib(nibName: "ReplyCell", bundle: nil), forCellReuseIdentifier: "ReplyCell")
tableView.register(UINib(nibName: "ReplyWithPhotoCell", bundle: nil), forCellReuseIdentifier: "ReplyWithPhotoCell")
tableView.register(UINib(nibName: "AnswerCell", bundle: nil), forCellReuseIdentifier: "AnswerCell")
//rx binding
tableView.rx.setDelegate(self).disposed(by: disposeBag)
tableView.rx.setDataSource(self).disposed(by: disposeBag)
_ = viewModel.questionDetail.asObservable().skip(1).subscribe(onNext:{details in
self.refreshControl.endRefreshing()
if let result = details.result, result == "OK"{
self.tableView.reloadData()
if(self.transition_id != nil){
//scrolldown to selected answer/reply
self.fromUserProfile()
}
self.updateQuestionInfo()
}else{
self.moveBack()
}
}).disposed(by:disposeBag)
if question != nil{
question_id = question.id!
setUp()
}
viewModel.getQuestionDetails(question_id: question_id)
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toUserPage))
self.userAvatar.isUserInteractionEnabled = true
self.userAvatar.addGestureRecognizer(tap)
let tap2: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toUserPage))
self.userNickname.isUserInteractionEnabled = true
self.userNickname.addGestureRecognizer(tap2)
(self.textView as UITextView).placeholder = "入力してください".localized
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.bookmark_label.text = "クリップ".localized
registerForKeyboardNotifications()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
unregisterForKeyboardNotifications()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let _ = viewModel.questionDetail.value.result {
switch section {
case 0:
return 1
case 1:
return viewModel.questionDetail.value.list.count
default:
return 0
}
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let questionDetail = self.viewModel.questionDetail.value
let cellType = identifyCellType(questionDetail: questionDetail, indexPath: indexPath)
print("Type \(cellType.0)")
let cell = tableView.dequeueReusableCell(withIdentifier: cellType.0, for: indexPath)
if let cell = cell as? CellConfiguraable{
switch cellType.1{
case 1:
cell.configure(questionDetail: questionDetail,delegate : self)
case 2:
cell.configure(answer: questionDetail.list.object(at: indexPath.row) as! Answer,delegate : self)
default:
cell.configure(reply: questionDetail.list.object(at: indexPath.row) as! Reply,delegate : self)
}
}
cell.selectionStyle = .none
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
guard let height = cellHeights[indexPath] else {
if(indexPath.section == 0){
return 600
}
return 118
}
return height
}
func identifyCellType(questionDetail : QuestionDetail,indexPath : IndexPath)-> (String,Int){
var reuseIdent : String = ""
var type : Int = 1
switch indexPath.section {
case 0:
if let image_urls = questionDetail.img_url_list{
switch image_urls.count{
case 0:
reuseIdent = "DetailsNoPhotoCell"
case 1:
reuseIdent = "DetailsOnePhotoCell"
default:
reuseIdent = "DetailsMultiPhotoCell"
}
}
type = 1
default:
if let answer = questionDetail.list.object(at: indexPath.row) as? Answer{
if let img_url = answer.img_url,img_url != ""{
reuseIdent = "AnswerWithPhotoCell"
}else{
reuseIdent = "AnswerCell"
}
type = 2
}else
if let reply = questionDetail.list.object(at: indexPath.row) as? Reply{
if let img_url = reply.img_url, img_url != ""{
reuseIdent = "ReplyWithPhotoCell"
}else{
reuseIdent = "ReplyCell"
}
type = 3
}
break
}
return (reuseIdent,type)
}
@objc func refresh(){
viewModel.getQuestionDetails(question_id: question_id)
}
func setUp(){
if let post_datetime = question.post_datetime{
date.text = Utils.getTimeAgo(text: post_datetime)
}
if let nickname = question.nickname{
userNickname.text = nickname
}
if let official = question.official, official == "1"{
official_widthConstraint.constant = 18
}
if let user_icon_url = question.user_icon_url{
userAvatar.sd_setImage(with: URL(string: user_icon_url)!,completed: { (image, error, type, url) in
})
}
}
func textViewDidChangeHeight(_ textView: GrowingTextView, height: CGFloat) {
UIView.animate(withDuration: 0.2) {
textView.superview?.layoutIfNeeded()
self.txtFieldContainer.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
func registerForKeyboardNotifications(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden), name: UIResponder.keyboardWillHideNotification, object: nil)
}
func unregisterForKeyboardNotifications(){
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(notification : NSNotification){
self.darkBackground.isHidden = false
if let keyboardRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardSize = keyboardRect.size
var bottomBarHeight : CGFloat = 44
if #available(iOS 11.0, tvOS 11.0, *) {
// with home indicator: 34.0 on iPhone X, XS, XS Max, XR.
if let bottomZoneHeight = UIApplication.shared.delegate?.window??.safeAreaInsets.bottom {
bottomBarHeight += bottomZoneHeight
}
}
textViewBottomConstraint.constant = keyboardSize.height - bottomBarHeight
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize.height
self.view.layoutIfNeeded()
}
}
//TextView Delegates
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let cursorPos = textView.offset(from: textView.beginningOfDocument, to: (textView.selectedTextRange?.start)!)
if range.length == 1 && text.count == 0 && cursorPos <= (self.reply_to_nickname.count+"さん".localized.count+1){
print("sdfsdf")
self.reply_target_id = 0
self.reply_answer_index = 0
self.reply_to_answer_id = 0
self.reply_to_nickname = ""
textView.text = ""
currentlyTyping = .Answer
return false
}
if((range.intersection(NSRange.init(location: 0, length: self.reply_to_nickname.count+"さん".localized.count))) != nil && self.reply_target_id != 0 && self.reply_target_id != AuthManager.sharedManager.getUser_id() ){
return false
}
return true
}
func textViewDidChangeSelection(_ textView: UITextView) {
let cursorPos = textView.offset(from: textView.beginningOfDocument, to: (textView.selectedTextRange?.start)!)
if(self.reply_to_nickname != "" ){
if(!endingEdit && cursorPos < (self.reply_to_nickname.count+"さん".localized.count+1) && self.reply_target_id != 0 && self.reply_target_id != AuthManager.sharedManager.getUser_id()){
textView.selectedRange = NSRange.init(location: textView.text.count, length: 0)
}
}
}
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
let cursorPos = textView.offset(from: textView.beginningOfDocument, to: (textView.selectedTextRange?.start)!)
if self.reply_target_id != 0 && cursorPos == (self.reply_to_nickname.count+"さん".localized.count){
textView.text.append("\n")
}
endingEdit = false
return true
}
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
endingEdit = true
self.tableView.reloadRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
return true
}
//Keyboard Notifications
@objc func keyboardWillBeHidden(notification : NSNotification){
self.darkBackground.isHidden = true
textViewBottomConstraint.constant = 10
var contentInset = UIEdgeInsets.zero
if ad_isOn {
contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: bannerView.frame.height, right: 0)
}
self.tableView.contentInset = contentInset
self.tableView.scrollIndicatorInsets = UIEdgeInsets.zero
self.view.layoutIfNeeded()
}
//Question Details Delegates
func answerButtonClick() {
self.textView.becomeFirstResponder()
currentlyTyping = .Answer
}
@ objc func imageAction(){
if(image == nil){
takeImage()
}else{
editImage()
}
}
func takeImage(){
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.sourceType = .photoLibrary
self.present(picker, animated: true, completion: nil)
showImagePicker = true
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
showImagePicker = false
imageURL = info[UIImagePickerController.InfoKey.referenceURL] as? URL
image = (info[UIImagePickerController.InfoKey.editedImage] as! UIImage)
self.cameraButton.setImage(image, for: .normal)
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
showImagePicker = false
dismiss(animated: true, completion: nil)
}
func editImage(){
let alertController = UIAlertController(title: "操作を選択してください".localized, message: "", preferredStyle: .actionSheet)
let sendButton = UIAlertAction(title: "画像を再選択する".localized, style: .default, handler: { (action) -> Void in
self.takeImage()
})
let deleteButton = UIAlertAction(title: "画像を削除する".localized, style: .destructive, handler: { (action) -> Void in
print("Delete button tapped")
let camera_icon = UIImage(named: "camera_icon")
self.cameraButton.setImage(camera_icon, for: .normal)
self.image = nil
self.imageURL = nil
})
let cancelButton = UIAlertAction(title: "キャンセル".localized, style: .cancel, handler: { (action) -> Void in
print("Cancel button tapped")
})
alertController.addAction(sendButton)
alertController.addAction(deleteButton)
alertController.addAction(cancelButton)
self.navigationController!.present(alertController, animated: true, completion: nil)
}
func showImagePager(images: [Image],index : Int) {
TabManager.sharedManager.showImagePager(images: images, index: index)
}
func showImage(image: String) {
TabManager.sharedManager.showImage(image: image)
}
func toUserProfile(user_id : Int){
TabManager.sharedManager.moveToUserPage(user_id: user_id)
}
func toMyProfile(){
TabManager.sharedManager.moveToProfile()
}
func pinQuestion(update_type: Int, completion: @escaping (Bool) -> ()) {
self.viewModel.favorite_question(question_id: self.question_id, update_type: update_type) { (response) in
if let result = response.result, result == "OK"{
self.notify_user(user_id: self.viewModel.questionDetail.value.user_id!)
if update_type == 1, response.notification! == "1" {
self.fav_push_notif()
}
self.update_bookmark_button(liked : update_type)
if self.checkUpdate != nil {
self.checkUpdate.value = true
self.checkUpdate.type = "update"
if(update_type == 1){
self.checkUpdate.question?.favorite_count = (self.checkUpdate.question?.favorite_count ?? 0) + 1
}else{
self.checkUpdate.question?.favorite_count = (self.checkUpdate.question?.favorite_count ?? 1) - 1
}
}
completion(true)
}else{
completion(false)
}
}
}
func likeQuestion(update_type: Int, completion:@escaping (Bool) -> ()) {
self.viewModel.like_question(question_id: self.question_id, update_type: update_type) { (response) in
if let result = response.result, result == "OK"{
completion(true)
self.notify_user(user_id: self.viewModel.questionDetail.value.user_id!)
if update_type == 1 && response.notification! == "1"{
self.like_question_notif()
}
if self.checkUpdate != nil {
self.checkUpdate.value = true
self.checkUpdate.type = "update"
if(update_type == 1){
self.checkUpdate.question?.like_count = (self.checkUpdate.question?.like_count ?? 0) + 1
self.checkUpdate.question?.like_flag = 1
}else{
self.checkUpdate.question?.like_count = (self.checkUpdate.question?.like_count ?? 1) - 1
self.checkUpdate.question?.like_flag = 0
}
}
}else{
completion(false)
}
}
}
func likeAnswer(answer: Answer, index: Int, update_type: Int, completion:@escaping (Bool) -> ()) {
self.viewModel.like_answer(answer_id: answer.id!, update_type: update_type) { (response) in
if let result = response.result, result == "OK"{
self.notify_user(user_id: answer.user_id!)
if update_type == 1 && response.notification == "1"{
let subindex : String.Index!
var title : String!
if answer.description!.characters.count >= 30{
subindex = answer.description!.index(answer.description!.startIndex, offsetBy: 30)
title = answer.description!.substring(to: subindex)
}else{
title = answer.description!
}
title = title.replacingOccurrences(of: "\n", with: " ")
self.like_answer_notif(title: title, device_token: answer.device_token!, answerDescription: answer.description!, answer_id: answer.id!)
}
completion(true)
}else{
completion(false)
}
}
}
func likeReply(reply: Reply, index: Int, update_type: Int, completion:@escaping (Bool) -> ()) {
self.viewModel.like_reply(reply_id: reply.id!, update_type: update_type) { (response) in
if let result = response.result, result == "OK"{
self.notify_user(user_id: reply.user_id!)
if update_type == 1 && response.notification == "1"{
let subindex : String.Index!
var title : String!
if reply.description!.characters.count >= 30{
subindex = reply.description!.index(reply.description!.startIndex, offsetBy: 30)
title = reply.description!.substring(to: subindex)
}else{
title = reply.description!
}
title = title.replacingOccurrences(of: "\n", with: " ")
self.like_reply_notif(title: title, device_token: reply.device_token!, replyDescription: reply.description!, reply_id: reply.id!)
}
completion(true)
}else{
completion(false)
}
}
}
func replyAnswer(answer: Answer,index : Int) {
currentlyTyping = .Reply
self.reply_target_id = answer.user_id!
self.reply_to_answer_id = answer.id
self.reply_to_nickname = "\(answer.nickname!)"
self.reply_answer_index = index
configTextViewForReply()
}
func replyReply(reply: Reply) {
currentlyTyping = .Reply
self.reply_target_id = reply.user_id!
self.reply_to_answer_id = reply.answer_id
self.reply_to_nickname = "\(reply.nickname!)"
let filtered = self.viewModel.questionDetail.value.list.filter {
guard let filtredanswer = $0 as? Answer, filtredanswer.id == reply.answer_id else{
return false
}
return true
}
for element in filtered {
if let replys_answer = element as? Answer{
self.reply_answer_index = self.viewModel.questionDetail.value.list.index(of: replys_answer)
}
}
configTextViewForReply()
}
func reportAnswer(answer_id: Int) {
let alertController = UIAlertController(title: "この返信を報告しますか?".localized, message: nil, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "報告する".localized, style: .destructive, handler: { (action) -> Void in
let homestoryboard = UIStoryboard(name: "HomeStoryboard", bundle: nil)
let reportViewController = homestoryboard.instantiateViewController(withIdentifier: "reportViewController") as! ReportViewController
reportViewController.answer_id = answer_id
TabManager.sharedManager.showVC(vc: reportViewController)
})
let deleteButton = UIAlertAction(title: "キャンセル".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(deleteButton)
alertController.addAction(sendButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func reportReply(reply_id: Int) {
let alertController = UIAlertController(title: "この投稿を報告しますか?".localized, message: nil, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "報告する".localized, style: .destructive, handler: { (action) -> Void in
let homestoryboard = UIStoryboard(name: "HomeStoryboard", bundle: nil)
let reportViewController = homestoryboard.instantiateViewController(withIdentifier: "reportViewController") as! ReportViewController
reportViewController.reply_id = reply_id
TabManager.sharedManager.showVC(vc: reportViewController)
})
let deleteButton = UIAlertAction(title: "キャンセル".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(deleteButton)
alertController.addAction(sendButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func reportQuestion() {
let alertController = UIAlertController(title: "この投稿を報告しますか?".localized, message: nil, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "報告する".localized, style: .destructive, handler: { (action) -> Void in
let homestoryboard = UIStoryboard(name: "HomeStoryboard", bundle: nil)
let reportViewController = homestoryboard.instantiateViewController(withIdentifier: "reportViewController") as! ReportViewController
reportViewController.question_id = self.question_id
TabManager.sharedManager.showVC(vc: reportViewController)
})
let deleteButton = UIAlertAction(title: "キャンセル".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(deleteButton)
alertController.addAction(sendButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func deleteQuestion(button : UIButton) {
let alertController = UIAlertController(title: "投稿削除".localized, message: "削除した投稿を復元することはできません。本当に削除しますか?".localized, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "はい".localized, style: .destructive, handler: { (action) -> Void in
self.delete_Question(question_id: self.question_id, button: button)
})
let deleteButton = UIAlertAction(title: "いいえ".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(sendButton)
alertController.addAction(deleteButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func deleteAnswer(answer: Answer,button : UIButton) {
let alertController = UIAlertController(title: "返信削除".localized, message: "削除した返信を復元することはできません。本当に削除しますか?".localized, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "はい".localized, style: .destructive, handler: { (action) -> Void in
//tmp index
let index = self.viewModel.questionDetail.value.list.index(of: answer)
//call delete
self.delete_Answer(index: index,button : button)
})
let deleteButton = UIAlertAction(title: "いいえ".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(sendButton)
alertController.addAction(deleteButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func deleteReply(reply: Reply,button:UIButton) {
let alertController = UIAlertController(title: "返信削除".localized, message: "削除した回答を復元することはできません。本当に削除しますか?".localized, preferredStyle: .alert)
let sendButton = UIAlertAction(title: "はい".localized, style: .destructive, handler: { (action) -> Void in
var answer_index : Int!
var filtered = [Any]()
filtered = self.viewModel.questionDetail.value.list.filter {
guard let filtredanswer = $0 as? Answer, filtredanswer.id == reply.answer_id else{
return false
}
return true
}
for element in filtered {
if let replys_answer = element as? Answer{
answer_index = self.viewModel.questionDetail.value.list.index(of: replys_answer)
}
}
let index = self.viewModel.questionDetail.value.list.index(of: reply)
self.delete_Reply(reply_id: "\(reply.id!)", index: index, answer_index: answer_index,button:button)
})
let deleteButton = UIAlertAction(title: "いいえ".localized, style: .default, handler: { (action) -> Void in
print("Delete button tapped")
})
alertController.addAction(sendButton)
alertController.addAction(deleteButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
func tagSelected(tagString: String) {
TabManager.sharedManager.toSearchScreen(keyword: tagString)
}
//Reply Config Textview
func configTextViewForReply(){
var attributedString : NSMutableAttributedString!
if(self.reply_to_nickname != UserManager.sharedManager.nickname ){
attributedString = NSMutableAttributedString(string: "\(self.reply_to_nickname)\("さん".localized)\n")
attributedString.addAttributes([
NSAttributedString.Key.font: UIFont(name: "HiraginoSans-W6", size: 14.0)!,
NSAttributedString.Key.foregroundColor: UIColor.black
], range: NSRange(location: 0, length: self.reply_to_nickname.count+"さん".localized.count))
attributedString.addAttributes([
NSAttributedString.Key.font: UIFont(name: "HiraginoSans-W3", size: 14.0)!,
NSAttributedString.Key.foregroundColor: UIColor.black
], range: NSRange(location: (self.reply_to_nickname.count)+"さん".localized.count,length: 1))
}
self.textView.attributedText = attributedString
textView.typingAttributes = [
NSAttributedString.Key.font: UIFont(name: "HiraginoSans-W3", size: 14)!,
NSAttributedString.Key.foregroundColor: UIColor.black
]
self.textView.becomeFirstResponder()
}
//Actions
@IBAction func sendAction(_ sender: Any) {
view.endEditing(true)
if let _ = self.viewModel.questionDetail.value.description{}else{
return
}
if validateTextLength(){
(sender as! UIButton).isEnabled = false
if currentlyTyping == .Reply{
post_reply()
}else{
post_answer()
}
}else{
textLengthAlert()
}
}
//Text Length alert
func textLengthAlert(){
let alertController = UIAlertController(title: "", message: "内容は2文字以上で入力してください。".localized, preferredStyle: .alert)
let okButton = UIAlertAction(title: "OK", style: .cancel, handler: { (action) -> Void in
print("ok button tapped")
})
alertController.addAction(okButton)
self.navigationController!.present(alertController, animated: true, completion: nil)
}
func validateTextLength() -> Bool {
if(currentlyTyping == .Reply){
if((self.textView.text.count < 2 && self.reply_target_id == AuthManager.sharedManager.user_id) || (self.textView.text.count < reply_to_nickname.count+san.localized.count+2 && self.reply_target_id != AuthManager.sharedManager.user_id) ){
return false
}
}else{
if(self.textView.text.count < 2){
return false
}
}
return true
}
@IBAction func backAction(_ sender: Any) {
moveBack()
}
func moveBack(){
TabManager.sharedManager.moveBack()
}
@IBAction func pinAction(_ sender: Any) {
var liked = 1
if let like_flag = self.viewModel.questionDetail.value.favorite_flag,like_flag == 1{
liked = 0
}
self.bookmark_button.isEnabled = false
let button = tableView.cellForRow(at: IndexPath.init(row: 0, section: 0))?.viewWithTag(306) as? UIButton
button?.isEnabled = false
viewModel.favorite_question(question_id: question_id, update_type: liked) { (response) in
button?.isEnabled = true
self.bookmark_button.isEnabled = true
if let result = response.result, result == "OK"{
if liked == 1{
self.viewModel.questionDetail.value.favorite_count! += 1
self.viewModel.questionDetail.value.favorite_flag = 1
//question.favorite_count += 1
}else{
self.viewModel.questionDetail.value.favorite_count! -= 1
self.viewModel.questionDetail.value.favorite_flag = 0
// question.favorite_count -= 1
}
self.notify_user(user_id: self.viewModel.questionDetail.value.user_id!)
if liked == 1, response.notification == "1" {
self.fav_push_notif()
}
self.update_bookmark_button(liked : liked)
if self.checkUpdate != nil {
self.checkUpdate.value = true
self.checkUpdate.type = "update"
if(liked == 1){
self.checkUpdate.question?.favorite_count = (self.checkUpdate.question?.favorite_count ?? 0) + 1
}else{
self.checkUpdate.question?.favorite_count = (self.checkUpdate.question?.favorite_count ?? 1) - 1
}
}
self.tableView.reloadRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
}
}
}
func update_bookmark_button(liked : Int){
if(liked == 1){
self.bookmark_button.setImage(UIImage.init(named: "icon_clip_on"), for: .normal)
}else{
self.bookmark_button.setImage(UIImage.init(named: "profile_pinned_on"), for: .normal)
}
}
//Post Answer/Reply
func post_answer(){
print("\n\n=========================POST ANSWER/REPLY====================")
if Utils.hasNgWord(textView.text) {
print("Has NGWord!")
// create the alert
let alert = UIAlertController(title: "禁止ワード", message: "公開できない単語が含まれています。".localized, preferredStyle: UIAlertController.Style.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
self.sendButton.isEnabled = true
// self.checkUpdate.value = true
// self.checkUpdate.type = "update"
// self.tableView.reloadData()
// self.post_ended()
return
}
print("==========================================================\n\n")
viewModel.post_answer(img_file: getImageData(), description: textView.text, question_id: question_id,completion:{response in
self.sendButton.isEnabled = true
if let result = response.result, result == "OK" {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(abbreviation: "JST")
let posteDate = formatter.string(from: Date())
var img_url = ""
if let imageData = self.getImageData(){
img_url = imageData.base64EncodedString(options: .lineLength64Characters)
}
let answerJson = ["id":response.answer_id!,
"user_id":AuthManager.sharedManager.getUser_id(),
"post_datetime":posteDate,
"nickname":UserManager.sharedManager.nickname,
"description":self.textView.text,
"user_icon_url":UserManager.sharedManager.user_icon_url,
"reply_count":0,
"good_count":0,
"official":UserManager.sharedManager.official,
"good_flag" :0,
"delete_flag":1,
"replies" : [],
"img_url":img_url] as [String : Any]
let submittedAnswer = Mapper<Answer>().map(JSON: answerJson)
self.viewModel.questionDetail.value.answer_count! += 1
if self.checkUpdate != nil {
self.checkUpdate.value = true
self.checkUpdate.type = "update"
self.checkUpdate.question?.answer_count = (self.checkUpdate.question?.answer_count ?? 0) + 1
}
//question.answer_count! += 1
self.viewModel.questionDetail.value.list.insert(submittedAnswer!, at: 0)
UIView.animate(withDuration: 0.2, animations: {
if self.tableView.numberOfRows(inSection: 1) > 0{
self.tableView.scrollToRow(at:IndexPath.init(row: 0, section: 1) , at: .bottom, animated: false)
}
}, completion: { (finished) in
self.tableView.reloadData()
})
self.notify_user(user_id: self.viewModel.questionDetail.value.user_id!)
if response.notification! == "1"{
let subindex : String.Index!
var title : String!
if self.textView.text.characters.count >= 30{
subindex = self.textView.text.index(self.textView.text.startIndex, offsetBy: 30)
title = self.textView.text.substring(to: subindex)
}else{
title = self.textView.text
}
title = title.replacingOccurrences(of: "\n", with: " ")
PushNotifManager.sharedManager.postNotification(activity_type: 1, title: title, device_token: self.viewModel.questionDetail.value.device_token!, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "\(response.answer_id!)", answerDescription: self.textView.text, reply_id: "", replyDescription:"")
}
self.post_ended()
}
})
}
func post_reply(){
print("\n\n=========================POST REPLY====================")
if Utils.hasNgWord(getReplyText()) {
print("Has NGWord!")
// create the alert
let alert = UIAlertController(title: "禁止ワード", message: "公開できない単語が含まれています。".localized, preferredStyle: UIAlertController.Style.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
self.sendButton.isEnabled = true
// self.checkUpdate.value = true
// self.checkUpdate.type = "update"
// self.tableView.reloadData()
// self.post_ended()
return
}
print("==========================================================\n\n")
viewModel.post_reply(img_file: getImageData(), description: getReplyText(), answer_id: self.reply_to_answer_id,reply_user_id: self.reply_target_id,completion:{response in
self.sendButton.isEnabled = true
if let result = response.result, result == "OK" {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(abbreviation: "JST")
let posteDate = formatter.string(from: Date())
var img_url = ""
if let imageData = self.getImageData(){
img_url = imageData.base64EncodedString(options: .lineLength64Characters)
}
let targetAnswer = self.viewModel.questionDetail.value.list.object(at: self.reply_answer_index) as! Answer
let replyJson = [
"id":response.reply_id!,
"user_id":AuthManager.sharedManager.getUser_id(),
"post_datetime":posteDate,
"nickname":UserManager.sharedManager.nickname,
"description":self.getReplyText(),
"user_icon_url":UserManager.sharedManager.user_icon_url,
"target_nickname":self.reply_to_nickname,
"good_count":0,
"good_flag":0,
"official":UserManager.sharedManager.official,
"delete_flag":1,
"img_url":img_url
] as [String : Any]
let submittedReply = Mapper<Reply>().map(JSON: replyJson)
targetAnswer.reply_count! += 1
submittedReply!.answer_id = targetAnswer.id!
targetAnswer.replies?.append(submittedReply!)
self.viewModel.questionDetail.value.list.insert(submittedReply!, at: (self.reply_answer_index!+targetAnswer.reply_count!))
self.tableView.reloadData()
self.tableView.scrollToRow(at: IndexPath.init(row: (self.reply_answer_index!+targetAnswer.reply_count!), section: 1),at: .bottom, animated: true)
self.currentlyTyping = .Answer
self.notify_user(user_id :targetAnswer.user_id! )
if response.notification! == "1"{
let subindex : String.Index!
var title : String!
if targetAnswer.description!.characters.count >= 30{
subindex = targetAnswer.description!.index(targetAnswer.description!.startIndex, offsetBy: 30)
title = targetAnswer.description!.substring(to: subindex)
}else{
title = targetAnswer.description!
}
title = title.replacingOccurrences(of: "\n", with: " ")
PushNotifManager.sharedManager.postNotification(activity_type: 3, title: title, device_token: targetAnswer.device_token!, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "", answerDescription: "", reply_id: "\(response.reply_id)", replyDescription: self.textView.text)
}
self.post_ended()
}
})
}
func post_ended(){
self.reply_target_id = 0
self.reply_answer_index = 0
self.reply_to_answer_id = 0
self.reply_to_nickname = ""
self.textView.text = ""
let camera_icon = UIImage(named: "camera_icon")
self.cameraButton.setImage(camera_icon, for: .normal)
self.image = nil
self.imageURL = nil
}
func getImageData()-> Data?{
if(self.image != nil){
let rect = CGRect.init(x:0,y: 0,width: self.image.size.width/2,height: self.image.size.height/2)
UIGraphicsBeginImageContext(rect.size)
self.image.draw(in: rect)
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImage!.jpegData(compressionQuality: 1.0)
}
return nil
}
override func refreshViewController() {
self.refresh()
}
func getReplyText()->String{
var replytext = self.textView.text
if(UserManager.sharedManager.nickname != self.reply_to_nickname){
replytext = self.textView.text.substring(from: String.Index.init(encodedOffset: self.reply_to_nickname.count + san.localized.count+1))
}
return replytext!
}
func fromUserProfile(){
var scrollToIndex : Int!
var filtered = [Any]()
if(self.transition_type! == 1){
filtered = self.viewModel.questionDetail.value.list.filter {
guard let filtredanswer = $0 as? Answer, filtredanswer.id == self.transition_id else{
return false
}
return true
}
if let result = self.viewModel.questionDetail.value.result, result != "OK"{
moveBack()
return
}
for element in filtered {
if let replys_answer = element as? Answer{
self.transition_scrollToIndex = self.viewModel.questionDetail.value.list.index(of: replys_answer)
}
}
}else{
filtered = self.viewModel.questionDetail.value.list.filter {
guard let filtredanswer = $0 as? Reply, filtredanswer.id == self.transition_id else{
return false
}
return true
}
for element in filtered {
if let replys_answer = element as? Reply{
self.transition_scrollToIndex = self.viewModel.questionDetail.value.list.index(of: replys_answer)
}
}
}
self.tableView.decelerationRate = UIScrollView.DecelerationRate.fast
UIView.animate(withDuration: 1, animations: {
if self.viewModel.questionDetail.value.list.count <= self.transition_scrollToIndex+1{
self.tableView.scrollToRow(at: IndexPath.init(row: self.transition_scrollToIndex, section: 1), at: .middle , animated: false)
}
})
self.transition_type = nil
self.transition_id = nil
}
func updateQuestionInfo(){
let questionDetail = self.viewModel.questionDetail.value
if let fav_flag = questionDetail.favorite_flag{
self.update_bookmark_button(liked: fav_flag)
}
self.userNickname.text = questionDetail.nickname!
self.date.text = Utils.getTimeAgo(text: questionDetail.poste_datetime!)
self.userAvatar.sd_setImage(with: URL.init(string: questionDetail.user_icon_url!), placeholderImage: UIImage(named: "avatar_placeholder"), options: [], completed: { (image, error, type, url) in
})
if(questionDetail.official! == "1"){
self.official_icon.isHidden = false
self.official_widthConstraint.constant = 18;
}else{
self.official_icon.isHidden = true
}
}
///////////// TIIIIIIT /////
func delete_Answer(index : Int,button : UIButton){
if (UserDefaults.standard.value(forKey: "access_token") != nil){
if !ReachabilityManager.shared.isNetworkAvailable{
let alertController = UIAlertController(title: "通信エラー".localized, message: "通信エラーが発生しました、再試行してください。".localized, preferredStyle: .alert)
let okButton = UIAlertAction(title: "再試行".localized, style: .cancel, handler: { (action) -> Void in
print("ok button tapped")
self.delete_Answer(index: index,button:button)
})
alertController.addAction(okButton)
TabManager.sharedManager.showAlert(alertController: alertController)
return
}
button.isEnabled = false
let answer = self.viewModel.questionDetail.value.list[index] as! Answer
HttpSSLManaged.manager.request(
Consts.BASIC_URL+"delete_answer",method : .post,
parameters: ["user_id": UserDefaults.standard.value(forKey: "user_id")!,"access_token":UserDefaults.standard.value(forKey: "access_token")!,"answer_id":"\(answer.id!)"]
)
.responseJSON { response in
guard response.result.isSuccess else {
//print("Error while fetching questions: \(response.result.error)")
button.isEnabled = true
return
}
print(response.result.value)
guard let responseJSON = response.result.value as? NSDictionary else {
//print("Error while parsing retult: \(response.result.error)")
button.isEnabled = true
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "AUTH_ERROR"){
button.isEnabled = true
TabManager.sharedManager.logout()
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "PARAM_ERROR"){
return
}
if(responseJSON.object(forKey: "result")as! String == "OK"){
self.viewModel.questionDetail.value.list.removeObject(at: index)
// if !(self.questionDetail.answers?.count == 4) {
var indexPaths = [IndexPath.init(row:index, section: 1)]
if(answer.reply_count! > 0){
for var i in 1...answer.reply_count!{
self.viewModel.questionDetail.value.list.removeObject(at: index)
indexPaths.append(IndexPath.init(row:index+i, section: 1))
}
}
button.isEnabled = true
self.tableView.reloadData()
self.viewModel.questionDetail.value.answer_count = self.viewModel.questionDetail.value.answer_count! - 1
self.tableView.reloadRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
if self.checkUpdate != nil {
self.checkUpdate.value = true
self.checkUpdate.type = "update"
self.checkUpdate.question?.answer_count = (self.checkUpdate.question?.answer_count ?? 1) - 1
}
}
}
}else{
Utils.logout(sourceVC: self)
return
}
}
func delete_Reply(reply_id : String,index: Int,answer_index : Int,button : UIButton){
let defaults = UserDefaults.standard
if ReachabilityManager.shared.isNetworkAvailable{
button.isEnabled = false
HttpSSLManaged.manager.request(
Consts.BASIC_URL+"delete_reply",method : .post,
parameters: ["user_id": defaults.value(forKey: "user_id")!,"access_token":defaults.value(forKey: "access_token")!,"reply_id":reply_id]
)
.responseJSON { response in
guard response.result.isSuccess else {
//print("Error while fetching questions: \(response.result.error)")
button.isEnabled = true
return
}
print(response.result.value)
guard let responseJSON = response.result.value as? NSDictionary else {
//print("Error while parsing retult: \(response.result.error)")
button.isEnabled = true
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "AUTH_ERROR"){
button.isEnabled = true
TabManager.sharedManager.logout()
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "PARAM_ERROR"){
button.isEnabled = true
return
}
if(responseJSON.object(forKey: "result")as! String == "OK"){
let answer = self.viewModel.questionDetail.value.list.object(at: answer_index) as! Answer
answer.reply_count! -= 1
self.tableView.reloadRows(at: [IndexPath.init(row: answer_index, section: 1)], with: .automatic)
self.viewModel.questionDetail.value.list.removeObject(at: index)
button.isEnabled = true
self.tableView.reloadData()
}
}
}
else{
let alertController = UIAlertController(title: "通信エラー".localized, message: "通信エラーが発生しました、再試行してください。".localized, preferredStyle: .alert)
let okButton = UIAlertAction(title: "再試行".localized, style: .cancel, handler: { (action) -> Void in
print("ok button tapped")
self.delete_Reply(reply_id: reply_id, index: index,answer_index: answer_index,button:button)
})
alertController.addAction(okButton)
TabManager.sharedManager.showAlert(alertController: alertController)
}
}
func delete_Question(question_id :Int,button: UIButton){
let defaults = UserDefaults.standard
if (defaults.value(forKey: "access_token") != nil){
if !ReachabilityManager.shared.isNetworkAvailable{
let alertController = UIAlertController(title: "通信エラー", message: "通信エラーが発生しました、再試行してください。", preferredStyle: .alert)
let okButton = UIAlertAction(title: "再試行", style: .cancel, handler: { (action) -> Void in
print("ok button tapped")
self.delete_Question(question_id: question_id,button:button)
})
alertController.addAction(okButton)
TabManager.sharedManager.showAlert(alertController: alertController)
return
}
button.isEnabled = false
HttpSSLManaged.manager.request(
Consts.BASIC_URL+"delete_question",method : .post,
parameters: ["user_id": defaults.value(forKey: "user_id")!,"access_token":defaults.value(forKey:"access_token")!,"question_id":question_id]
)
.responseJSON { response in
guard response.result.isSuccess else {
//print("Error while fetching questions: \(response.result.error)")
button.isEnabled = true
return
}
print(response.result.value)
guard let responseJSON = response.result.value as? NSDictionary else {
//print("Error while parsing retult: \(response.result.error)")
button.isEnabled = true
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "AUTH_ERROR"){
button.isEnabled = true
TabManager.sharedManager.logout()
return
}
if((response.value as AnyObject).object(forKey: "result") as! String == "PARAM_ERROR"){
button.isEnabled = true
return
}
if(responseJSON.value(forKey: "result") as! String == "OK"){
//TODO update home
self.checkUpdate.value = true
self.checkUpdate.type = "delete"
TabManager.sharedManager.moveBack()
}
}
}else{
Utils.logout(sourceVC: self)
return
}
}
@objc func toUserPage(){
if let user_id = self.viewModel.questionDetail.value.user_id{
if user_id != AuthManager.sharedManager.user_id{
toUserProfile(user_id: user_id)
}else{
toMyProfile()
}
}
}
func addBannerViewToView(_ bannerView: GADBannerView) {
bannerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(bannerView)
view.addConstraints(
[NSLayoutConstraint(item: bannerView,
attribute: .bottom,
relatedBy: .equal,
toItem: self.txtFieldContainer,
attribute: .top,
multiplier: 1,
constant: 0),
NSLayoutConstraint(item: bannerView,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1,
constant: 0)
])
}
/// Tells the delegate an ad request loaded an ad.
func adViewDidReceiveAd(_ bannerView: GADBannerView) {
print("adViewDidReceiveAd")
addBannerViewToView(bannerView)
self.tableView.contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: bannerView.frame.height, right: 0)
ad_isOn = true
}
/// Tells the delegate an ad request failed.
func adView(_ bannerView: GADBannerView,
didFailToReceiveAdWithError error: GADRequestError) {
print("adView:didFailToReceiveAdWithError: \(error.localizedDescription)")
}
/// Tells the delegate that a full-screen view will be presented in response
/// to the user clicking on an ad.
func adViewWillPresentScreen(_ bannerView: GADBannerView) {
print("adViewWillPresentScreen")
}
/// Tells the delegate that the full-screen view will be dismissed.
func adViewWillDismissScreen(_ bannerView: GADBannerView) {
print("adViewWillDismissScreen")
self.tableView.contentInset = UIEdgeInsets.zero
}
/// Tells the delegate that the full-screen view has been dismissed.
func adViewDidDismissScreen(_ bannerView: GADBannerView) {
print("adViewDidDismissScreen")
}
/// Tells the delegate that a user click will open another app (such as
/// the App Store), backgrounding the current app.
func adViewWillLeaveApplication(_ bannerView: GADBannerView) {
print("adViewWillLeaveApplication")
}
func fav_push_notif(){
let description = self.viewModel.questionDetail.value.description!
let subindex : String.Index!
var title : String!
if description.characters.count >= 30{
subindex = description.index(self.viewModel.questionDetail.value.description!.startIndex, offsetBy: 30)
title = description.substring(to: subindex)
}else{
title = description
}
title = title.replacingOccurrences(of: "\n", with: " ")
PushNotifManager.sharedManager.postNotification(activity_type: 2, title: title, device_token: self.viewModel.questionDetail.value.device_token!, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "", answerDescription: "", reply_id: "", replyDescription: "")
}
func like_question_notif(){
let description = self.viewModel.questionDetail.value.description!
let subindex : String.Index!
var title : String!
if description.characters.count >= 30{
subindex = description.index(self.viewModel.questionDetail.value.description!.startIndex, offsetBy: 30)
title = description.substring(to: subindex)
}else{
title = description
}
title = title.replacingOccurrences(of: "\n", with: " ")
PushNotifManager.sharedManager.postNotification(activity_type: 7, title: title, device_token: self.viewModel.questionDetail.value.device_token!, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "", answerDescription: "", reply_id: "", replyDescription: "")
}
func like_reply_notif(title : String,device_token : String,replyDescription : String,reply_id:Int){
PushNotifManager.sharedManager.postNotification(activity_type: 6, title: title, device_token: device_token, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "", answerDescription: "", reply_id: "\(reply_id)", replyDescription: replyDescription)
}
func like_answer_notif(title : String,device_token : String,answerDescription: String,answer_id:Int){
PushNotifManager.sharedManager.postNotification(activity_type: 4, title: title, device_token: device_token, question_id: "\(self.question_id!)", question_description: self.viewModel.questionDetail.value.description!, answer_id: "\(answer_id)", answerDescription: answerDescription, reply_id: "", replyDescription: "")
}
func notify_user(user_id:Int){
SocketIOManager.sharedManager.notify(id: user_id)
}
}
Voici ensuite le contenu du fichier DetailsNoPhotoCell.swift :
A partir de DetailsNoPhotoCell.swift (quand j'execute l'action: google_translate_Action) je souhaite pouvoir acceder aux description des reponses (les reponses sont le fichier AnswerCell.swift).
Le hic c'est que comme c'est mon 1er projet, je ne vois pas du tout comment faire...
Ouch le fichier de 1600 lignes... Je vais pas lire 2000 lignes (si j'ajoute les deux autres bout de code après). Va falloir isoler un peu les différents sujets. Je suis pas certain que tout le fichier soit concerné par ton soucis.
Comme je disais, deux cells ne peuvent pas communiquer entre elles. C'est au contrôleur d'orchestrer ça.
Actuellement, tu passes answer à ta cell Answer. Pourquoi ne pourrais-tu pas faire la même chose ?
Pourquoi as-tu besoin des descriptions des réponses dans les autres cellules ? google_translate_action n'est pas censé traduire le texte ?
Pour l'instant c'est plus le fonctionnement qui m'intéresse que le code.
Desole pour le long pave de codes (je n'aime pas ca non plus lorsque j'essaie d'aider les membres du forums sur des probleme de javascript. C'est pour ca que dans mon 1er message j'avais essaye de donner que les elements qui me paressait pertinent)
Je t'explique ce que je dois faire et peut etre que tu pourras mieux me guider.
Je dois ajouter un bouton google translate et quand on clique dessus, les textes doivent etre traduit.
- j'ai reussi a integrer Google translate dans mon application (et ca fontionne)
- j'arrive a traduire la description de la question
- maintenant je dois traduire la description des reponses. Ca fait 3 jours que je cherche sans succes
Mon soucis c'est que le bouton (le @IBAction) est creer dans une autre class et je n'ai mais alors aucune idee de ce que je dois faire.
Si tu as le temps et que cela ne te derange pas. Pourrais tu me donner un exemple d'une telle situation:
- 1 controller
- 2 elements (donc 2 classe differents)
- un bouton qui se trouve dans le 1er element et qui me permet d'acceder a l'autre element
"Actuellement, tu passes answer à ta cell Answer. Pourquoi ne pourrais-tu pas faire la même chose ?"
---> je peux modifier le code il n'y pas de soucis.
Qu'est ce que tu entends par "faire la meme chose" ?
Moi ce que je pensai faire ou pouvoir faire: c'est depuis ma Cell acceder au controller
Puis ensuite dans le controller je comptai creer une methode me permettant de mofidier toutes mes reponses.
Est ce une mauvaise approche ? Je lutte pour justement acceder au controller depuis ma cell. Donc je ne sais pas comment proceder.
Je crois avoir une piste la. Je t'explique ce que j'ai fais (comme ca tu pourras mieux m'assister/me conseiller).
1. Dans mon fichier QuestionDetailsViewController.swift j'ai cree une methode:
func jojoTest() {
print("Hello World")
}
2. Dans mon fichier QuestionDetailDelegate.swift j'ai ajoute ce code:
func jojoTest()
3. Dans mon fichier DetailsNoPhotoCell.swift dans mon @IBAction j'ai rajoute :
self.questionDetailsDelegate?.jojoTest()
Apres avoir fait un test le Hello World s'affiche bien dans ma console. J'ai donc reussi a acceder au controller par cette methode
Donc si je ne me trompe pas (corrige moi si je fais fausse route stp), maintenant il ne me reste plus qu'a trouver le moyen de manipuler les answers depuis le controller ?
(Moi je vais sur cette voie en attendant ta reponse).
Tu peux passer dans jojoTest la langue voulue ou n'importe quel truc dont t'as besoin pour l'opération de traduction. Un seul paramètre ce serait mieux. Quitte à faire une enum ou une struct si la data est un peu plus complexe.
Ensuite tu peux rajouter dans ton protocol CellConfigurable (de mémoire) à la méthode configure(...) un paramètre pour renvoyer l'info de la langue.
Un reloadData à la fin de jojoTest() et c'est bon.
Maintenant je dois essayer de voir comment faire passer une variable d'une vue a une autre (ou controller a un autre ... je ne sais pas encore comment proceder): en gros, lorsque l'on est dans une vue A quand on clique sur un bouton 1, ca swipe (ca change donc de vue) on arrive dans la vue B eh bien il faut que j'arrive a savoir qu'on cliquer sur ce bouton 1 (et pas le bouton 2 qui nous fait egalement arrive sur la vue B).
===>Mais avant de te demander ton aide, je vais chercher tout seul et voir si j'y arrive.
Bref un grand merci pour ton temps et tes explications
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.