Reputation: 9
I'm trying to use a segue to pass through some user input from a custom alert but for some reason when I perform the segue the view on the app doesn't change. But the viewdidload on the destination view controller runs, I know this because I put a print statement inside it.
More Detail
I have 3 classes here STAlert(MyCustom Alert), WorkoutLibraryViewController(The initial VC), STAddExerciseViewController(The Destination VC),
The WorkoutLib VC is connected to the Exercise VC via show segue with the "addWorkout" Identifier.
WorkoutLibraryViewController Class
import UIKit
class WorkoutLibraryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
@IBOutlet weak var WorkoutList: UITableView!
var workouts:[Workout] = []
let customAlert = STAlerts()
@IBOutlet weak var addWorkoutButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
WorkoutList.delegate = self
WorkoutList.dataSource = self
view.backgroundColor = Colors.navyBlue
// Do any additional setup after loading the view.
}
@IBAction func didTapCreateWorkout(_ sender: Any) {
customAlert.showAlert(with: "hello world", messege: "name?", on: self)
print("workoutBTN")
}
@objc func didTapDoneAlert(){
customAlert.didTapDoneAlert()
print("Did Tap Done")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addWorkout"{
if let destinationVC = segue.destination as? STAddExerciseViewController {
destinationVC.workoutName = customAlert.userInput
print("preformed Seguea to \(destinationVC) WorkoutViewController")
}
else{
print("DestinationVC not set")
}
}else{
print("Couldn't find segue identifier")
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
// MARK: - UITableViewDataSource Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return workouts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "WorkoutCell", for: indexPath)
let workout = workouts[indexPath.row]
cell.textLabel?.text = workout.name
// Configure the cell as needed
return cell
}
// MARK: - UITableViewDelegate Methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Handle row selection
}
}
STAlert
import Foundation
import UIKit
class STAlerts: NSObject, UITextFieldDelegate{
private var backgroundView: UIView = {
let backgroundView = UIView()
backgroundView.backgroundColor = .black
backgroundView.alpha = 0
return backgroundView
}()
private let alertView: UIView = {
let alert = UIView()
alert.backgroundColor = Colors.greyBlue
alert.layer.masksToBounds = true
alert.layer.cornerRadius = 12
return alert
}()
private var myTargetView:UIView?
var userInput: String? // user input value
func showAlert(with title:String, messege:String, on viewController: UIViewController){
guard let targetView = viewController.view else {
return
}
myTargetView = targetView
backgroundView.frame = targetView.bounds
targetView.addSubview(backgroundView)
targetView.addSubview(alertView)
alertView.frame = CGRect(x: 40, y: -300 , width: targetView.frame.size.width-80, height: 300)
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: alertView.frame.size.width, height: 80))
titleLabel.text = title
titleLabel.textColor = Colors.white
titleLabel.textAlignment = .center
alertView.addSubview(titleLabel)
let msgLabel = UILabel(frame: CGRect(x: 0, y: titleLabel.frame.minY + 10, width: alertView.frame.size.width, height: 80))
msgLabel.numberOfLines = 0
msgLabel.text = messege
msgLabel.textColor = Colors.white
msgLabel.textAlignment = .center
alertView.addSubview(msgLabel)
//<-------------------textField---------------->
let textField = STTextField(frame: CGRect(x: 0, y: msgLabel.frame.maxY + 10 , width: alertView.frame.size.width-10, height: 20))
textField.delegate = self // set Delegate
textField.placeholder = {
let placeHolders:[String] = ["Push & Pull Split", "Arm Day", "Bodyweight Routine"]
return placeHolders[Int.random(in: 0..<placeHolders.count)]
}()
func textFieldShouldReturn(_ textField: STTextField) -> Bool {
textField.resignFirstResponder()
return true
}
alertView.addSubview(textField)
// <---------------------button------------------->
let button = UIButton(frame: CGRect(x: 0,
y: alertView.frame.size.height-50,
width: alertView.frame.size.width,
height: 50))
alertView.addSubview(button)
button.setTitle("Done", for: .normal)
button.setTitleColor(Colors.energyOrange, for: .normal)
button.addTarget(self, action: #selector(didTapDoneAlert), for:.touchUpInside)
UIView.animate(withDuration: 0.25, animations: {
self.backgroundView.alpha = 0.6
}, completion: { done in
if done{
UIView.animate(withDuration: 0.25, animations: {
self.alertView.center = targetView.center })
}
})
}
@objc func didTapDoneAlert(){
guard let targetView = myTargetView else{
print("Error: targetView is nil")
return
}
UIView.animate(withDuration: 0.25, animations: {
self.alertView.frame = CGRect(x: 40, y: -300 , width: targetView.frame.size.width-80, height: 300)
},
completion:{ done in
if done{
UIView.animate(withDuration: 0.25, animations: {
self.backgroundView.alpha = 0
},
completion: {done in
if done{
self.backgroundView.removeFromSuperview()
self.alertView.removeFromSuperview()
if let viewController = targetView.parentViewController() as? WorkoutLibraryViewController {
print("Segue performed on view controller: \(viewController) AlertView")
viewController.performSegue(withIdentifier: "addWorkout", sender: self)
}else{
print("Error: Unable to find view controller to perform segue")
}
}})
}
})
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
userInput = textField.text?.isEmpty == true ? textField.placeholder : textField.text
return true
}
//<-------------------- Navigation -------------->
}
extension UIView {
func parentViewController() -> UIViewController? {
var parentResponder: UIResponder? = self
while let responder = parentResponder {
parentResponder = responder.next
if let viewController = responder as? UIViewController {
return viewController
}
}
return nil
}
}
STAddExerciseViewController
import UIKit
class STAddExerciseViewController: UIViewController, UITableViewDataSource, STExerciseTableViewCellDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var workoutTitle: UILabel!
@IBOutlet weak var doneBtn: UIButton!
@IBOutlet weak var table: UITableView!
var workoutName:String?
var filter:[Exercise]!
var newExercises:[Exercise] = []
var exercises:[Exercise] = [Exercise(name: "Pushup", video: "pushup"), Exercise(name: "Pullup", video: "pullup"), Exercise(name: "Situp", video: "situp"), Exercise(name: "Bicep Curl", video: "bicepcurl" ), Exercise(name: "Hammer Curl", video: "hammercurl"), Exercise(name: "Barbell Curl", video: "barbellcurl"), Exercise(name: "Inclined Dumbell Curl", video: "inclinedcurl"), Exercise(name: "Spider Curl", video: "spidercurl"), Exercise(name: "Squat", video: "squat"),Exercise(name: "DeadLift", video: "deadlift"), Exercise(name: "Crunch", video: "crunch"), Exercise(name: "Russian Twist", video: "russiantwist")]
override func viewDidLoad() {
super.viewDidLoad()
print("Adding workout")
self.view.backgroundColor = Colors.navyBlue
filter = exercises
workoutTitle.text = workoutName
table.register(STExerciseTableViewCell.nib(), forCellReuseIdentifier: STExerciseTableViewCell.identifier)
table.dataSource = self
while newExercises.count == 0{
doneBtn.titleLabel?.text = "Cancel"
}
// Do any additional setup after loading the view.
}
func didTapButton(with exercise: Exercise) {
print(exercise.name)
for i in 0..<newExercises.count{
if newExercises[i].name == exercise.name{
newExercises.remove(at: i)
}
else{
newExercises.append(exercise)
}
}
doneBtn.titleLabel?.text = "Add \(newExercises.count) Exercises"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exercises.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: STExerciseTableViewCell.identifier, for: indexPath) as! STExerciseTableViewCell
cell.configure(with: exercises[indexPath.row])
cell.delegate = self
return cell
}
@IBAction func didTapDone(_ sender: Any) {
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
*/
}
Right now my console gives me:
Segue performed on view controller: <StrengthTree_JSM_.WorkoutLibraryViewController: 0x10d9076a0> AlertView
preformed Seguea to <StrengthTree_JSM_.STAddExerciseViewController: 0x10db3c9e0> WorkoutViewController
nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
Adding workout
nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
Im useing Xcode Version 15.4 on storyboard
Upvotes: 0
Views: 57