How to reload self ViewController with few changes in swift? - ios

I have a customVC nib view in which tableview items are displaying from url .Now on clicking a button here I need to reload the same viewcontroller with some other request sent to api . My data is again reloading and the response is coming but only tableview data is not changing based on the response. The old data is still loading...
class CustomAddOnVC: UIViewController,UITableViewDataSource,UITableViewDelegate {
var myAddOnUrl = "http://\(platform).eposapi.co.uk/?app_id=\(apiID)&app_key=\(apikey)&request=addon&aid=\(PASSADDON!)"
#IBAction func ContinueBtn(sender: AnyObject){
if checkCount == 0{
print("Please Select one Item")
}else{
if addOnNext != 0
{
//here i am changing my request for url
PASSADDON = String(addOnNext!)
print(PASSADDON)
let customVC = CustomAddOnVC()
customVC.modalPresentationStyle = .OverCurrentContext
presentViewController(customVC, animated: true, completion: nil)
dismissViewControllerAnimated(false, completion: nil)
}
}
my screen shots

Related

PHPickerViewController's Cancel Button is not working in iOS 15

I am using PHPickerViewController to pick Image for User Profile Picture Purpose in iOS 15. I am using UIKit framework. I have the following code:
var pickerConfig = PHPickerConfiguration(photoLibrary: .shared())
pickerConfig.selectionLimit = 1
pickerConfig.filter = .images
let pickerView = PHPickerViewController(configuration: pickerConfig)
pickerView.delegate = self
self.present(pickerView, animated: true)
The Picker is working properly for selecting images and delegating the results. But, when the Cancel button is pressed, nothing happens and the Picker is not dismissed as expected.
How to dismiss the PHPickerViewController instance when its own Cancel button is pressed ?
Edit:
The implementation of PHPickerViewControllerDelegate Method is as follows:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult])
{
results.first?.itemProvider.loadObject(ofClass: UIImage.self) { [unowned self] reading , error in
guard let image = reading as? UIImage, error == nil else
{
DispatchQueue.main.async {
picker.dismiss(animated: true)
self.profilePictureHasError = true
self.toggleDoneButtonEnabled()
}
return
}
self.profilePictureHasError = false
DispatchQueue.main.async {
picker.dismiss(animated: true)
self.profilePictureHasChanged = self.userProfilePicture != image
if self.profilePictureHasChanged
{
self.profilePictureView.image = image
self.toggleDoneButtonEnabled()
}
}
}
}
You need to dismiss the picker yourself in the picker(_:didFinishPicking:) delegate method which is called when the user completes a selection or when they tap the cancel button.
From the Apple docs for picker(_:didFinishPicking:):
The system doesn’t automatically dismiss the picker after calling this method.
For example:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// Do something with the results here
picker.dismiss(animated: true)
}
Your current delegate code only calls picker.dismiss when the results array is non-empty (i.e when the user has selected images). When the cancel button is tapped, the delegate method is called with an empty results array.
Fix the issue by adding the following to the top of the code in your delegate method:
if results.isEmpty {
picker.dismiss(animated: true)
return
}
you just wrap it out in an objc func for making cancel button works
#objc
func didOpenPhotos() {
lazy var pickerConfig = PHPickerConfiguration()
pickerConfig.filter = .images
pickerConfig.selectionLimit = 1
let pickerView = PHPickerViewController(configuration: pickerConfig)
pickerView.delegate = self
self.present(pickerView, animated: true)
}
call it anywhere

Reloading TableView when a UIViewController is being dismissed?

The problem here is that I'm presenting EditCommentVC modally, over the current context of the CommentVC because I want to set the background of the UIView to semi-transparent. Now, on the EditCommentVC I have a UITextView that allows the user to edit their comment, along with 2 buttons - cancel (dismisses the EditCommentVC) and update that updates the new comment and push it to the database.
In term of code, everything is working, except that once the new comment is being pushed and EditCommentVC is being dismissed, the UITableView on CommentsVC with all the comments is not being reloaded to show the updated comments. Tried calling it from viewWillAppear() but it doesn't work.
How can I reload the data in the UITableView in this case?
#IBAction func updateTapped(_ sender: UIButton) {
guard let id = commentId else { return }
Api.Comment.updateComment(forCommentId: id, updatedComment: editTextView.text!, onSuccess: {
DispatchQueue.main.async {
let commentVC = CommentVC()
commentVC.tableView.reloadData()
self.dismiss(animated: true, completion: nil)
}
}, onError: { error in
SVProgressHUD.showError(withStatus: error)
})
}
The code in the CommentVC where it transitions (and passes the id of the comment). CommentVC conforms to a CommentActionProtocol that passes the id of that comment:
extension CommentVC: CommentActionProtocol {
func presentActionSheet(for commentId: String) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let editAction = UIAlertAction(title: "Edit", style: .default) { _ in
self.performSegue(withIdentifier: "CommentVCToEditComment", sender: commentId)
}
actionSheet.addAction(editAction)
present(actionSheet, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "CommentVCToEditComment" {
let editCommentVC = segue.destination as! EditCommentVC
let commentId = sender as! String
editCommentVC.commentId = commentId
}
}
}
I see atleast 2 problems here:
You are creating a new CommentVC which you should not do if you want to update the tableView in the existing view controller.
Since you have mentioned that Api.Comment.updateComment is a an asynchronous call, you need to write the UI code to run on the main thread.
So first you need to have the instance of the commentVC in a variable inside this viewController. You can store the instance of the view controller from where you are presenting this view controller.
class EditCommentVC {
var commentVCdelegate: CommentVC!
// Rest of your code
}
Now you need to pass the reference commentVC in this variable when you are presenting the edit view controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "CommentVCToEditComment" {
let editCommentVC = segue.destination as! EditCommentVC
let commentId = sender as! String
editCommentVC.commentId = commentId
editCommentVC.commentVCdelegate = self
}
}
Now you need to use this reference to reload your tableView.
Api.Comment.updateComment(forCommentId: id, updatedComment: editTextView.text!, onSuccess: {
DispatchQueue.main.async {
commentVCdelegate.tableView.reloadData() // - this commentVC must be an instance that you store of the your commentVC that you created the first time
self.dismiss(animated: true, completion: nil)
}
}, onError: { error in
SVProgressHUD.showError(withStatus: error)
})
Well, i had this problem too, and the solution i found was to use Protocol. I would recommend you to search how to send data back to previous ViewController. That way, when you dismiss the EditCommentVC, you then send back a value(in my case i send true) to the previous ViewController(in your case, CommentVC), and then you'll have a function in CommentVC checking if the value is true and if it is, reload the TableView.
Here, let me show you an example of how i used (those are the names of my ViewControllers, functions and protocols, you can use whatever you want and send whatever data you want back):
In your CommentVC, you'll have something like this:
protocol esconderBlurProtocol {
func isEsconder(value: Bool)
}
class PalestranteVC: UIViewController,esconderBlurProtocol {
func isEsconder(value: Bool) {
if(value){
//here is where you can call your api again if you want and reload the data
tableView.reloadData()
}
}
}
Also, dont forget that you have to set the delegate of EditCommentVC, so do it when you're presenting EditCommentVC, like this:
let viewController = (self.storyboard?.instantiateViewController(withIdentifier: "DetalhePalestranteVC")) as! DetalhePalestranteVC
viewController.modalPresentationStyle = .overFullScreen
viewController.delegate = self
self.present(viewController, animated: true, completion: nil)
//replace **DetalhePalestranteVC** with your **EditCommentVC**
And in your EditCommentVC you'll have something like this:
class DetalhePalestranteVC: UIViewController {
var delegate: esconderBlurProtocol?
override func viewWillDisappear(_ animated: Bool) {
delegate?.isEsconder(value: true)
}
}
That way, everything you dismiss EditCommentVC, you'll send back True and reload the tableView.

SWIFT 4 Present viewcontroller

I am trying to building a app using the master details template.
in the Master view controller I added a button called Catalogue : this button showing a tabbar controller called Catalogue.
I don't use Segue to show the catalogue, I use the code below to show the tab controller
From Master form I called the Tabbar controller :
#IBAction func Btn_Catalogue(_ sender: Any) {
let AddCatalogueVC = self.storyboard?.instantiateViewController(withIdentifier: "CatalogueVC") as! CatalogueVC
present(AddCatalogueVC, animated: true, completion: nil)
}
From CategorieVC I use the code below to show
#IBAction func Btn_AddCategorie(_ sender: Any) {
self.Mode = "New"
let AddCategorieViewController = self.storyboard?.instantiateViewController(withIdentifier: "AddCategorieVC") as! AddCategorieVC
present(AddCategorieViewController, animated: true, completion: nil)
}
I dismiss the AddCategorieVC using the code below
#IBAction func Btn_Save(_ sender: Any)
{
if self.Txt_CategorieName.text != ""{
self.Mysave = true
self.MyCategorieName = self.Txt_CategorieName.text!
self.dismiss(animated: true, completion: nil)
}
}
I have unwind SEGUE from Save button to a function in categorieVC
#IBAction func FctSaveCategories(_ sender: UIStoryboardSegue) {
let sendervc = sender.source as! AddCategorieVC
if self.Mode == "New" && sendervc.Mysave == true { // Mode insert
let MyCategories = TblCategorie(context: Mycontext)
MyCategories.categorie_Name = sendervc.MyCategorieName
do {
try Mycontext.save()
} catch {
debugPrint ("there is an error \(error.localizedDescription)")
}
}
}
The problem is when I hit the save button in categorieVC the catalogueVC is also dismissing at the same time returning me to the master control.
I am almost sure that the problem came from the Unwind segue but I don't know why.
Update: I activate the Cancel button in AddCategorieVC with the code below
self.dismiss(animated: true, completion: nil)
and when I clicked on it only the AddCategorieVC is being dismissed and I go back to CatalogueVC. The difference between the save button and the Cancel Button is only the UNWIND segue on the Save Button.
And when I add UnWIND segue to the cancel Button (just to test the behavior) it took me back to the master form instead CatalogueVC.
How can I solve that?
And yesss I found it
It look like that unwind segue automaticly handled dismiss contrôle
So all I need to do is remove the dismiss code from the save button this way the unwind segue will took me back to catalogueVC.
.

Passing data between two view controllers are not working

I am trying to pass some data between two view controllers, but it doesn't work..
This is the data i am trying to pass(these has items from parse.com - the same code is in both view controllers):
var userFile = [PFFile]()
var createdAt = [NSDate]()
var objID = [String]()
This is the button for open the view controller(inside the first view controller i am trying to send data FROM):
#IBAction func openButtonAction(sender: AnyObject) {
let modalVC = ModalViewController(nibName: "ModalViewController", bundle: nil)
modalVC.userFile = self.userFile
modalVC.createdAt = self.createdAt
modalVC.objID = self.objID
print("USERFILE: \(modalVC.userFile.count)")
presentViewController(modalVC, animated: true, completion: nil)
}
The view controller is a ModalViewController.xib connected to ViewStoryModalViewController.swift
This is the viewDidLoad in the view controller i am trying to send data TO:
override func viewDidLoad() {
super.viewDidLoad()
print("USERFILECOUNT: \(self.userFile.count)")
}
My problem is that this is the messages i get in xCode output:
What might be wrong here? Any suggestions?
xCode output tells that an array self.userFile contains zero elements, It doesn't mean that it is passed wrong. It is just empty.
print("USERFILECOUNT: \(self.userFile.count)")
Check if it is empty before passing it to modal vc.
Try this code
You first need to present after that try to set variable.
IBAction func openButtonAction(sender: AnyObject) {
let modalVC = ModalViewController(nibName: "ModalViewController", bundle: nil)
print("USERFILE: \(modalVC.userFile.count)")
presentViewController(modalVC, animated: true, completion: nil)
modalVC.userFile = self.userFile
modalVC.createdAt = self.createdAt
modalVC.objID = self.objID
}

navigation ios 8 swift?

I am new to the IOS world. I having trouble changing view when im switching to a new view which only can be shown when I login. I am using inside the loginfuction:
#IBAction func loginVerification(sender: UIButton!) {
//Check with the cloud
//temporary faking credentials
var user = "n"
var pass = "n"
if usernameLogin.text == user &&
passwordLogin.text == pass
{
println("Correct credentials")
let homeviewcontroller = HomeViewController()
self.presentViewController(homeviewcontroller, animated: true, completion: nil)
}
else
{
println("Wrong credentials!!")
}
}
The function above is triggered when I press the login button which checks for credentials.
Using the lines above makes the view black. Any suggestions on how to make it work? Any tutorial I can follow on navigation between views? And please don't be so hard on me :)
Thanks in advance!
Hi I would try the Apple tutorials - they are fairly well written and have code samples. Here is one that I used when I was learning: https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/SecondTutorial.html. This one is specifically about navigating using Storyboards and Segues. If you look on the left of the page, you'll see links to other tutorials that may be helpful for you when getting started.
Try the following code:
let controller: homeviewcontroller = self.storyboard?.instantiateViewControllerWithIdentifier("homeviewcontroller") as! homeviewcontroller
self.presentViewController(controller, animated: true, completion: nil)
#IBAction func loginVerification(sender: UIButton!) {
//Check with the cloud
//temporary faking credentials
var user = "n"
var pass = "n"
if usernameLogin.text == user &&
passwordLogin.text == pass
{
println("Correct credentials")
let controller: homeviewcontroller = self.storyboard?.instantiateViewControllerWithIdentifier("homeviewcontroller") as! homeviewcontroller
self.presentViewController(controller, animated: true, completion: nil)
}
else
{
println("Wrong credentials!!")
}
}

Resources