selecting with UIButton and moving a specific model data with segue - swift

I am new to swift and new to programming in general. I am building a quiz app. I want to select a topic in a TopicViewController and move to a new Quizviewcontroller that will display the question and answer choices. I have multiple question bank that I believe are objects of a class Question. I am able to move to the QuizViewConctroller with segue but unable to select the Question bank based on the topic UI button selected.
I have tried and spent days trying to figure this out. I have looked at similar posts in SO. I have posted this question before but did not get any reply. I would really appreciate if someone could help. I don't know how else to proceed...
TopicsViewController:
import UIKit
class TopicsViewController: UIViewController, ReturnToTopicVCDelegate {
func goToTopicVC() {}
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func goToQuestionsVCWhenPressed(_ sender: UIButton) {
performSegue(withIdentifier: "segueToQuestionVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToQuestionVC" {
let quizVC = segue.destination as! QuizViewController
quizVC.delegate = self
}
}
}
QuizViewController:
import UIKit
import QuartzCore
protocol ReturnToTopicVCDelegate {
func goToTopicVC()
}
class QuizViewController: UIViewController {
var delegate: ReturnToTopicVCDelegate?
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var questionImageView: UIImageView!
#IBOutlet weak var optionAButton: UIButton!
#IBOutlet weak var optionBButton: UIButton!
#IBOutlet weak var optionCButton: UIButton!
#IBOutlet weak var optionDButton: UIButton!
#IBOutlet weak var optionEButton: UIButton!
//outlets for the progress
#IBOutlet weak var questionCounter: UILabel!
#IBOutlet weak var scoreLabel: UILabel!
var allQuestions = QuestionBank()
var selectedAnswer: Int = 0 // answer selected by the subject
var questionNumber: Int = 0
var score: Int = 0
#IBAction func answerPressed(_ sender: UIButton) {
if sender.tag == selectedAnswer {
print("correct answer")
sender.backgroundColor = .green
score += 1
} else {
print("wrong")
sender.backgroundColor = .red
print("\(allQuestions.list[questionNumber].correctAnswer)")
//the following two lines change the right answer button to green using the tag value of the button
let correctAnswerButton = view.viewWithTag(selectedAnswer) as? UIButton
correctAnswerButton?.backgroundColor = UIColor.green
}
}
#IBAction func GoToNextQuestion(_ sender: UIButton) {
questionNumber += 1
nextQuestion()
}
func nextQuestion() {
if questionNumber <= allQuestions.list.count - 1 {
questionLabel.text = allQuestions.list[questionNumber].question
questionImageView.image = UIImage(named: (allQuestions.list[questionNumber].questionImage))
optionAButton.setTitle(allQuestions.list[questionNumber].optionA, for: .normal)
optionBButton.setTitle(allQuestions.list[questionNumber].optionB, for: .normal)
optionCButton.setTitle(allQuestions.list[questionNumber].optionC, for: .normal)
optionDButton.setTitle(allQuestions.list[questionNumber].optionD, for: .normal)
optionEButton.setTitle(allQuestions.list[questionNumber].optionE, for: .normal)
selectedAnswer = allQuestions.list[questionNumber].correctAnswer
updateUI()
} else {
let alert = UIAlertController(title: "Great!", message: "Do you want to start over?", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Restart", style: .default) { (UIAlertAction) in
self.restartQuiz()
}
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}
}
func updateUI() {
scoreLabel.text = "score: \(score)"
questionCounter.text = "\(questionNumber + 1)/\(allQuestions.list.count)"
}
func restartQuiz() {
score = 0
questionNumber = 0
nextQuestion()
}
#IBAction func goBackToTopicsVC(_ sender: Any) {
delegate?.goToTopicVC()
dismiss(animated: true, completion: nil)
}
}
The Questions are in this format
import Foundation
class QuestionBank {
var list = [Question]()
init() {
let skyColorQuestion = Question(questionText: “What is the color of sky?", image: "sky", choiceA: "blue", choiceB: "black", choiceC: "yellow", choiceD: "pink", choiceE: "None of the above", answer: 1)
let whatQuestion = Question(questionText: “what…?”, image: "image", choiceA: "x", choiceB: "y", choiceC: "z", choiceD: "m", choiceE: "None of the above", answer: 3)
list.append(skyColorQuestion)
list.append(whatQuestion)
}
}
Navigation Pane
Storyboard

Add the data are not correct in this way. My recommendation you can use a Realm, sqLite, CoreData or FireBase.

Related

Force unwrapping nil optional for UIImageView when transitioning to view controller

I'm running into an error when transitioning to view controllers by overriding the built-in prepare() function in Swift. I have a UIImageView for backgrounds on my screens. Here is the code for two of the view controllers in question.
import UIKit
import FirebaseAuth
class HomeVC: UIViewController {
#IBOutlet weak var signOutButton: UIButton!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendsNavButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var profileNavButton: UIButton!
#IBOutlet weak var bumpButton: UIButton!
#IBOutlet weak var welcomeLabel: UILabel!
#IBOutlet weak var doNotDisturbLabel: UILabel!
#IBOutlet weak var doNotDisturbButton: UIButton!
var userName = ""
var dndIsOn: Bool = false
#IBAction func dndToggled(_ sender: Any) {
dndIsOn = !dndIsOn
User.current.available = !dndIsOn
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).updateData([Constants.Firestore.Keys.available : !dndIsOn])
if dndIsOn {
print("DND is on!")
setupDNDUI()
} else if !dndIsOn {
print("DND is off!")
setupActiveUI()
}
}
#IBAction func signOutTapped(_ sender: Any) {
let firAuth = Auth.auth()
do {
try firAuth.signOut()
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
print("Successfully signed out")
}
#IBAction func bumpTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toCall, sender: self)
}
#IBAction func friendsNavTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toFriends, sender: self)
}
#IBAction func profileNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(ProfileVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
doNotDisturbLabel.isHidden = true
if !userName.isEmpty {
welcomeLabel.text = "Welcome Back, " + userName + "!"
} else {
welcomeLabel.text = ""
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let friendsVC = segue.destination as? FriendsVC else {
return
}
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).getDocument { (snapshot, err) in
if let err = err {
print(err.localizedDescription)
} else {
let data = snapshot!.data()!
let requests = data[Constants.Firestore.Keys.requests] as? [String]
if let requests = requests {
friendsVC.requests = requests
}
}
}
}
class FriendsVC: UIViewController {
//var friends: [Friend] = User.current.friends
var friends: [User] = []
var requests: [String]?
#IBOutlet weak var requestsNumberLabel: UILabel!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendRequestsButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var friendsTitle: UILabel!
#IBOutlet weak var friendTableView: UITableView!
#IBOutlet weak var addFriendButton: UIButton!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint!
#IBAction func friendRequestsTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toRequests, sender: self)
}
#IBAction func homeNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(HomeVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
friendTableView.backgroundView?.backgroundColor = .white
friendsTitle.isHidden = false
UserService.getUserArray(uids: User.current.friendUids, completion: { (users) in
guard let users = users else {
print("User has no friends")
return
}
self.friends = users
self.friendTableView.reloadData()
})
guard let requests = self.requests else {
friendRequestsButton.isHidden = true
requestsNumberLabel.isHidden = true
self.tableViewTopConstraint.constant = 0
return
}
requestsNumberLabel.text = requests.count.description
// Do any additional setup after loading the view.
friendTableView.delegate = self
friendTableView.dataSource = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let homeVC = segue.destination as? HomeVC {
homeVC.userName = User.current.firstName
} else if let requestsVC = segue.destination as? RequestsVC {
UserService.getUserArray(uids: self.requests!) { (requesters) in
if let requesters = requesters {
requestsVC.requesters = requesters
}
}
}
}
}
When my app loads into the home screen, there is no problem, and when a button is tapped to transition to FriendsVC, there is no problem. However, when I try to initiate the transition from HomeVC to ProfileVC or from FriendVC to HomeVC, I get the error: "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" at the self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill lines in my viewDidLoad methods. These segues have something in common in that these are the ones where I override the prepare() function, but I'm not sure what I'm doing wrong

Swift: Why can I pass info from one IBAction to another, but not to a function

I am trying to get the values for splitValue and tipPercent into the getSettings() at the bottom. Why can I get the values for both of those in the IBAction calculatePressed, but when I try to get the values into the function the value is nil. I am sooo confused. Thank you for the help!
#IBOutlet weak var billTextField: UITextField!
#IBOutlet weak var zeroPctButton: UIButton!
#IBOutlet weak var tenPctButton: UIButton!
#IBOutlet weak var twentyPctButton: UIButton!
#IBOutlet weak var splitNumberLabel: UILabel!
var tipChosen = ""
var totalPerPerson = ""
var tipPercent = ""
var splitValue = ""
#IBAction func tipChanged(_ sender: UIButton) {
tipPercent = sender.currentTitle!
if sender.isSelected == true {
return
}
zeroPctButton.isSelected = false
tenPctButton.isSelected = false
twentyPctButton.isSelected = false
sender.isSelected = true
if sender.currentTitle == "0%" {
tipChosen = "0.00"
} else if sender.currentTitle == "10%" {
tipChosen = "0.10"
} else if sender.currentTitle == "20%" {
tipChosen = "0.20"
}
billTextField.endEditing(true)
}
#IBAction func stepperValueChanged(_ sender: UIStepper) {
splitValue = String(Int(sender.value))
splitNumberLabel.text = String(Int(sender.value))
}
#IBAction func calculatePressed(_ sender: UIButton) {
let bill = Float(billTextField.text!)!
let tip = Float(tipChosen)!
let tax = bill * tip
let splitNumber = Float(splitNumberLabel.text!)
let total = (bill + tax) / Float(splitNumber!)
totalPerPerson = "$\(String(format: "%.2f", total))"
performSegue(withIdentifier: "goToTotal", sender: self)
}
func getSettings() -> String {
return "Split between \(splitValue) people, with a \(tipPercent) tip."
}
Ok, sorry it took me a bit, but I finally think I understand what I did.
class CalculatorViewController: UIViewController {
var tip = 0.0
var finalBill = ""
var split = 2
#IBOutlet weak var billTextField: UITextField!
#IBOutlet weak var zeroPctButton: UIButton!
#IBOutlet weak var tenPctButton: UIButton!
#IBOutlet weak var twentyPctButton: UIButton!
#IBOutlet weak var splitNumberLabel: UILabel!
#IBAction func tipChanged(_ sender: UIButton) {
if sender.isSelected == false {
sender.isSelected = false
} else if sender.isSelected == true {
sender.isSelected = true
}
zeroPctButton.isSelected = false
tenPctButton.isSelected = false
twentyPctButton.isSelected = false
sender.isSelected = true
billTextField.endEditing(true)
}
#IBAction func stepperValueChanged(_ sender: UIStepper) {
splitNumberLabel.text = Int(sender.value).description
}
#IBAction func calculatePressed(_ sender: UIButton) {
if zeroPctButton.isSelected == true {
tip = 0.0
} else if tenPctButton.isSelected == true {
tip = 0.1
} else if twentyPctButton.isSelected == true {
tip = 0.2
}
print(tip)
let bill = Double(billTextField.text!)
split = Int(Double(splitNumberLabel.text!)!)
if billTextField.text != "" {
let billWithTip = (bill! * tip) + bill!
let billWithTipSplit = billWithTip / Double(split)
finalBill = String(format: "%.2f", billWithTipSplit)
print(billWithTip)
}
self.performSegue(withIdentifier: "getResults", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "getResults" {
let destinationVC = segue.destination as! ResultsViewController
destinationVC.finalBill = finalBill
destinationVC.split = split
destinationVC.tip = tip
}
}
}
class ResultsViewController: UIViewController {
#IBOutlet weak var totalLabel: UILabel!
#IBOutlet weak var settingsLabel: UILabel!
var tip = 0.0
var split = 2
var finalBill = ""
override func viewDidLoad() {
super.viewDidLoad()
totalLabel.text = "$\(finalBill)"
settingsLabel.text = "Split between \(Int(split)) people, with a \(Int(tip * 100))% tip"
}
#IBAction func recalculatePressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
I did what you suggested with the string and some minor calculations on the second view controller, changed the values of a few declared properties and got rid of the getSettings(). I was under the impression that I couldn't pass data without a return value from a function. Thank you for the help!

How do I set my variable correctly to a value on Firebase and not have it reset the progress?

Everytime I leave this ViewController and then come back the quiz starts back to question 1. I want it to resume from where I left off.
I believe why it keeps resetting to zero is because my initial "questionNumber" is set to 0 but I'm not sure how to set its value to the value in Firebase correctly. I get error after error. I've tried so many different ways but none of them seem to work and resume from where I left off.
Thanks for your help! PLEASE help me!
class CryptoViewController: UIViewController {
var questionList = CryptoBank()
var score = 0
var pickedQuestion = 0
var uid = FIRAuth.auth()?.currentUser?.uid
var questionNumber = 0
#IBOutlet weak var questionViewer: UILabel!
#IBOutlet weak var choiceOne: UIButton!
#IBOutlet weak var choiceTwo: UIButton!
#IBOutlet weak var choiceThree: UIButton!
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var questionNumberView: UILabel!
#IBOutlet weak var progressBarView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
choiceOne.titleLabel?.textAlignment = NSTextAlignment.center
choiceTwo.titleLabel?.textAlignment = NSTextAlignment.center
choiceThree.titleLabel?.textAlignment = NSTextAlignment.center
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = .clear
update()
}
#IBAction func buttonPressed(_ sender: AnyObject) {
if sender.tag == 1 {
pickedQuestion = 1}
else if sender.tag == 2 {
pickedQuestion = 2}
else if sender.tag == 3 {
pickedQuestion = 3}
checkAnswer()
questionNumber += 1
nextQuestion()
}
func checkAnswer(){
let correctAnswer = questionList.cryptoBank[questionNumber].answer
if pickedQuestion == correctAnswer {
score += 1
}else{
print("Wrong Answer")
}
}
func updateFirebase(){
let ref = FIRDatabase.database().reference()
guard let uid = FIRAuth.auth()?.currentUser!.uid else{
return}
ref.child("Users").child(uid).child("Cryptoquiz").child("Question Number").setValue(questionNumber)
ref.child("Users").child(uid).child("Cryptoquiz").child("Score").setValue(score)
}
func nextQuestion(){
if questionNumber <= 9 {
update()
} else{
scoreLabel.text = "Score: \(score)"
let alert = UIAlertController(title: "Done!", message: "Would you like to restart?", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Restart", style: .default, handler: { (UIAlertAction) in
self.startAgain()
})
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}}
func update(){
let nextQuest = questionList.cryptoBank[questionNumber]
questionViewer.text = nextQuest.question
choiceOne.setTitle(nextQuest.choice1, for: .normal)
choiceTwo.setTitle(nextQuest.choice2, for: .normal)
choiceThree.setTitle(nextQuest.choice3, for: .normal)
scoreLabel.text = "Score: \(score)"
questionNumberView.text = "Question: \(questionNumber + 1)"
progressBarView.frame.size.width = (view.frame.size.width/9) * CGFloat(questionNumber + 1)
updateFirebase()
}
}
You can save your progress in UserDefaults in viewDidDisappear() like this:
UserDefaults.standard.set(questionNumber, forKey: "questionNumber")
And then every time you open your view, in viewDidLoad() or in viewDidAppear() you update your questionNumber like this:
let questionNumberSaved = UserDefaults.standard.integer(forKey: “questionNumber”) ?? 0
questionNumber = questionNumberSaved
Then after doing this you call your updateFirebase() method

Moving data from Model to destination ViewController with segue

I am new to Swift and programming in general. I am building a quiz app. The app uses TopicsViewController to select a topic and segue to a QuestionsViewController. The questions for the various topics are stored as separate Swift Objects file. I would like to pick the Topic1 Question file when I press the topic1 button in TopicsViewController to segue into the QuestionsViewController. I would like to know how can I select the particular questions file QuestionBank1/QuestionBank2 when I select the particular topic upon segueing to the QuestionsViewController?
Navigation Pane :
Main.storyboard :
TopicsViewController:
import UIKit
class TopicsViewController: UIViewController, returnToTopicVCDelegate {
func goToTopicVC() {
}
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func goToQuestionsVCWhenPressed(_ sender: UIButton) {
performSegue(withIdentifier: "segueToQuestionVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueToQuestionVC" {
let quizVC = segue.destination as! QuizViewController
quizVC.delegate = self
}
}
}
QuizViewController:
import UIKit
import QuartzCore
protocol returnToTopicVCDelegate{
func goToTopicVC()
}
class QuizViewController: UIViewController {
var delegate : returnToTopicVCDelegate?
//outlet for the question label and image view
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var questionImageView: UIImageView!
//outlet for the buttons
#IBOutlet weak var optionAButton: UIButton!
#IBOutlet weak var optionBButton: UIButton!
#IBOutlet weak var optionCButton: UIButton!
#IBOutlet weak var optionDButton: UIButton!
#IBOutlet weak var optionEButton: UIButton!
//outlets for the progress
#IBOutlet weak var questionCounter: UILabel!
#IBOutlet weak var scoreLabel: UILabel!
var allQuestions = QuestionBank()
var selectedAnswer : Int = 0 // answer selected by the subject
var questionNumber: Int = 0
var score: Int = 0
// functions executed after an answer is picked
#IBAction func answerPressed(_ sender: UIButton) {
if sender.tag == selectedAnswer {
print("correct answer")
sender.backgroundColor = .green
score += 1
} else {
print("wrong")
sender.backgroundColor = .red
print("\(allQuestions.list[questionNumber].correctAnswer)")
//the following two lines change the right answer button to green using the tag value of the button
let correctAnswerButton = view.viewWithTag(selectedAnswer) as? UIButton
correctAnswerButton?.backgroundColor = UIColor.green
}
}
#IBAction func GoToNextQuestion(_ sender: UIButton) {
questionNumber += 1
nextQuestion()
}
// selects a new questions and updates the score
func nextQuestion(){
if questionNumber <= allQuestions.list.count - 1 {
questionLabel.text = allQuestions.list[questionNumber].question
questionImageView.image = UIImage(named: (allQuestions.list[questionNumber].questionImage))
optionAButton.setTitle(allQuestions.list[questionNumber].optionA, for: UIControlState.normal)
optionBButton.setTitle(allQuestions.list[questionNumber].optionB, for: UIControlState.normal)
optionCButton.setTitle(allQuestions.list[questionNumber].optionC, for: UIControlState.normal)
optionDButton.setTitle(allQuestions.list[questionNumber].optionD, for: UIControlState.normal)
optionEButton.setTitle(allQuestions.list[questionNumber].optionE, for: UIControlState.normal)
selectedAnswer = allQuestions.list[questionNumber].correctAnswer
updateUI()
} else {
let alert = UIAlertController(title: "Great!", message: "Do you want to start over?", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Restart", style: .default) {(UIAlertAction) in
self.restartQuiz()
}
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}
}
func updateUI(){
scoreLabel.text = "score: \(score)"
questionCounter.text = "\(questionNumber + 1)/\(allQuestions.list.count)"
}
func restartQuiz(){
score = 0
questionNumber = 0
nextQuestion()
}
#IBAction func goBackToTopicsVC(_ sender: Any) {
delegate?.goToTopicVC()
dismiss(animated: true, completion: nil)
}
}
You can use the following steps :
1- Add a segue from TopicsViewController to QuestionsViewController and give the segue "Identifier Name " from Attributes inspector.
2- Add a variable in QuestionsViewController for the topic lets name it "topicType".
3- Override the below function in TopicsViewController and send the name of the topic with the segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Identifier Name" {
if let destinationviewController = segue.destination as? QuestionsViewController , let buttonPressed = sender as? UIButton {
destinationviewController.topicType = buttonPressed.currentTitle!
}
}
}
4- For each button in TopicsViewController , get the button action and type the following function in it :
#IBAction func topicButton(_ sender: UIButton) {
performSegue(withIdentifier: "Identifier Name", sender: nil)
}
I hope this helps you .

Sharing Dictionary with UIActivityViewController in Swift

I'm new to Swift. I'm in process of making a shopping list app. There are two UITextField, one for the item name and the other for the item quantity that saves to the dictionary. I would like to share this list with UIActivityViewController, but it only shares the last value. Can someone advice me how to share all item and amount with the UIActivityViewController.
var shoppinglist = [String:String]()
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Amount: UITextField!
#IBAction func Add(_ sender: UIButton) {
var item = Item.text!
var amount = Amount.text!
shoppinglist [item] = amount
print(shoppinglist)
}
#IBAction func share(_ sender: UIButton) {
let activityController = UIActivityViewController(activityItems: [shoppinglist], applicationActivities: nil)
present(activityController,animated: true,completion: nil)
}
}
Try following code. I hope this coding helps for you.
class shoppinglist:NSObject {
var yourItem:String = ""
var amount:Int = 0
init(yourItem:String, amount:Int) {
self.yourItem = yourItem
self.amount = amount
}
}
Declare the variables inside your class
var shoppingListArray = [shoppinglist]()
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Amount: UITextField!
#IBAction func Add(_ sender: UIButton) {
self.shoppingListArray.append(shoppinglist(yourItem:Item.text, amount:Int(Amount.text!)!))
print(shoppingListArray)
}
#IBAction func share(_ sender: UIButton) {
let activityController = UIActivityViewController(activityItems: shoppingListArray, applicationActivities: nil)
present(activityController,animated: true,completion: nil)
}
}
try this:-
#IBAction func share(_ sender: UIButton) {
let activityVc = UIActivityViewController(activityItems: ["here your item name","item quantity"], applicationActivities:nil)
activityVc.popoverPresentationController?.sourceView = self.view
self.present(activityVc, animated:true, completion:nil)
}