I`ve made an birthday reminder project.I have BirthdayVC and in there there are plus buttons when I tap on it - popUpVC pops up.In popUpVC I ned to fill the form with data and this data(name and age) should be visible in BirthdayVC.But it's not visible in BirthdayVC I have a protocol, set popUpVc.delegate = self.I don't know why it doesn't working
BirthdayVC.swift
protocol BirthdayVCDelegate: AnyObject {
func update(name: String, age: String, time: Date)
}
class BirthdayVC: UIViewController, BirthdayVCDelegate {
private let nameLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 10, weight: .regular)
label.textColor = UIColor.red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let ageLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 10, weight: .regular)
label.textColor = UIColor.red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
navigationItem.title = "Birthday"
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addProfile))
[nameLabel, ageLabel].forEach { subview in
view.addSubview(subview)
}
applyConstraints()
}
@objc func addProfile() {
let popUpVc = PopUpVC()
if let sheeet = popUpVc.sheetPresentationController {
sheeet.detents = [.large()]
}
present(popUpVc, animated: true, completion: nil)
popUpVc.delegate = self
}
func update(name: String, age: String, time: Date) {
nameLabel.text? = name.capitalized
ageLabel.text? = age " years"
}
func applyConstraints() {
NSLayoutConstraint.activate([
nameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 30),
nameLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
nameLabel.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: -10),
nameLabel.widthAnchor.constraint(equalToConstant: 200),
ageLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 10),
ageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
ageLabel.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: -10),
ageLabel.widthAnchor.constraint(equalToConstant: 200)
])
}
}
popUpVC.swift
import UIKit
import Photos
import PhotosUI
class PopUpVC: UIViewController {
weak var delegate: BirthdayVCDelegate?
//MARK: DONEBUTTON
private let DoneButton: UIButton = {
let button = UIButton()
button.setTitle("Done", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(dismissSheet), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
private let profileImageView: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "person")
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private let changeImageButton: UIButton = {
let button = UIButton()
button.setTitle("Change Image", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(changeImage), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
//MARK: Name label && textfield
private let nameLabel: UILabel = {
let label = UILabel()
label.text = "Name"
label.textColor = UIColor.blue
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let nameTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Name"
textField.font = UIFont.systemFont(ofSize: 15)
textField.borderStyle = .roundedRect
textField.autocorrectionType = .default
textField.keyboardType = .default
textField.returnKeyType = .done
textField.clearButtonMode = .whileEditing
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
//MARK: Date label && textfield
private let dateLabel: UILabel = {
let label = UILabel()
label.text = "Date of birth"
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.textColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let dateTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Pick date"
textField.font = UIFont.systemFont(ofSize: 15)
textField.borderStyle = .roundedRect
textField.autocorrectionType = .default
textField.keyboardType = .default
textField.returnKeyType = .done
textField.clearButtonMode = .whileEditing
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
//MARK: Age label && textfield && picker
private let ageLabel: UILabel = {
let label = UILabel()
label.text = "Age"
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.textColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let agePicker: UIPickerView = {
let picker = UIPickerView()
picker.translatesAutoresizingMaskIntoConstraints = false
return picker
}()
let ageTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Pick your age"
textField.font = UIFont.systemFont(ofSize: 15)
textField.borderStyle = .roundedRect
textField.autocorrectionType = .default
textField.keyboardType = .default
textField.returnKeyType = .done
textField.clearButtonMode = .whileEditing
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
//MARK: Sex label && textfield && picker
private let genreLabel: UILabel = {
let label = UILabel()
label.text = "Genre"
label.font = UIFont.systemFont(ofSize: 20, weight: .regular)
label.textColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let genreTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Pick genre"
textField.font = UIFont.systemFont(ofSize: 15)
textField.borderStyle = .roundedRect
textField.autocorrectionType = .default
textField.keyboardType = .default
textField.returnKeyType = .done
textField.clearButtonMode = .whileEditing
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
private let genrePicker: UIPickerView = {
let picker = UIPickerView()
picker.translatesAutoresizingMaskIntoConstraints = false
return picker
}()
//MARK: Instagram label && textfield
private let instagramLabel: UILabel = {
let label = UILabel()
label.text = "Instagram"
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.textColor = UIColor.blue
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let instagramTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Pick genre"
textField.font = UIFont.systemFont(ofSize: 15)
textField.borderStyle = .roundedRect
textField.autocorrectionType = .default
textField.keyboardType = .default
textField.returnKeyType = .done
textField.clearButtonMode = .whileEditing
textField.addTarget(self, action: #selector(didRecogniseTapGesture), for: UIControl.Event.editingDidBegin)
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
//MARK: Face ID label && switch
let genre = ["Male", "Female", "Unknown"]
let age = Array(1...100)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .purple
agePicker.tag = 0
genrePicker.tag = 1
view.addSubview(profileImageView)
view.addSubview(changeImageButton)
view.addSubview(nameLabel)
view.addSubview(nameTextField)
view.addSubview(dateLabel)
view.addSubview(dateTextField)
dateTextField.datePicker(target: self, doneAction: #selector(doneAction), cancelAction: #selector(cancelAction))
view.addSubview(ageLabel)
view.addSubview(ageTextField)
ageTextField.inputView = agePicker
// picker
agePicker.dataSource = self
agePicker.delegate = self
// genre label && textfield
view.addSubview(genreLabel)
view.addSubview(genreTextField)
genreTextField.inputView = genrePicker
//
genrePicker.delegate = self
genrePicker.dataSource = self
// instagram label && textfield
view.addSubview(instagramLabel)
view.addSubview(instagramTextField)
view.addSubview(DoneButton)
applyConstraints()
view.backgroundColor = .white
}
//MARK: dateTextfield methods
@objc func cancelAction() {
self.dateTextField.resignFirstResponder()
}
@objc func doneAction() {
if let datePicker = self.dateTextField.inputView as? UIDatePicker {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: datePicker.date)
self.dateTextField.text = dateString
}
self.dateTextField.resignFirstResponder()
}
//MARK: Instagram textfield
@objc func didRecogniseTapGesture() {
showInstagramAlert()
}
@objc func dismissSheet() {
dismiss(animated: true, completion: nil)
delegate?.update(name: nameTextField.text!, age: ageTextField.text!, time: Date())
}
@objc func changeImage() {
var config = PHPickerConfiguration(photoLibrary: .shared())
config.selectionLimit = 1
config.filter = PHPickerFilter.images
let vc = PHPickerViewController(configuration: config)
vc.delegate = self
present(vc, animated: true)
}
func showInstagramAlert() {
let alertController = UIAlertController(title: "Instagram nikname", message: "Enter your instagram nikname", preferredStyle: .alert)
alertController.addTextField { word in
word.placeholder = "Your nickName"
}
let ok = UIAlertAction(title: "Ok", style: .cancel) { action in
let text = alertController.textFields?.first
self.instagramTextField.text! = (text?.text!)!
}
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
private func applyConstraints() {
let DoneButtonConstrains = [
DoneButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
DoneButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10)
]
let personImageConstrains = [
profileImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 60),
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
// profileImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 80),
// profileImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -80),
profileImageView.widthAnchor.constraint(equalToConstant: 80),
profileImageView.heightAnchor.constraint(equalToConstant: 90)
]
let changeImageButtonConstrains = [
changeImageButton.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 10),
//changeImageButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -120)
changeImageButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
]
let nameLabelConstrains = [
nameLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
nameLabel.topAnchor.constraint(equalTo: changeImageButton.bottomAnchor, constant: 30),
]
let nameTextFieldConstrains = [
nameTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
nameTextField.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 15),
nameTextField.widthAnchor.constraint(equalToConstant: 300)
]
let dateLabelConstrains = [
dateLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
dateLabel.topAnchor.constraint(equalTo: nameTextField.bottomAnchor, constant: 15)
]
let dateTextfieldConstrains = [
dateTextField.topAnchor.constraint(equalTo: dateLabel.bottomAnchor, constant: 15),
dateTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
dateTextField.widthAnchor.constraint(equalToConstant: 300)
]
let ageLabelConstrains = [
ageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
ageLabel.topAnchor.constraint(equalTo: dateTextField.bottomAnchor, constant: 15)
]
let agePickerConstrains = [
ageTextField.topAnchor.constraint(equalTo: ageLabel.bottomAnchor, constant: 15),
ageTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
ageTextField.widthAnchor.constraint(equalToConstant: 300)
]
let genreLabelConstrains = [
genreLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
genreLabel.topAnchor.constraint(equalTo: ageTextField.bottomAnchor, constant: 15)
]
let gennreTextFieldConstrains = [
genreTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
genreTextField.topAnchor.constraint(equalTo: genreLabel.bottomAnchor, constant: 15),
genreTextField.widthAnchor.constraint(equalToConstant: 300)
]
let instagramLabelConstrains = [
instagramLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
instagramLabel.topAnchor.constraint(equalTo: genreTextField.bottomAnchor, constant: 15)
]
let instagramTextFieldConstrains = [
instagramTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
instagramTextField.topAnchor.constraint(equalTo: instagramLabel.bottomAnchor, constant: 15),
instagramTextField.widthAnchor.constraint(equalToConstant: 300)
]
NSLayoutConstraint.activate(DoneButtonConstrains)
NSLayoutConstraint.activate(nameLabelConstrains)
NSLayoutConstraint.activate(nameTextFieldConstrains)
NSLayoutConstraint.activate(personImageConstrains)
NSLayoutConstraint.activate(changeImageButtonConstrains)
NSLayoutConstraint.activate(dateLabelConstrains)
NSLayoutConstraint.activate(dateTextfieldConstrains)
NSLayoutConstraint.activate(ageLabelConstrains)
NSLayoutConstraint.activate(agePickerConstrains)
NSLayoutConstraint.activate(genreLabelConstrains)
NSLayoutConstraint.activate(gennreTextFieldConstrains)
NSLayoutConstraint.activate(instagramLabelConstrains)
NSLayoutConstraint.activate(instagramTextFieldConstrains)
}
}
extension PopUpVC: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
results.forEach { results in
results.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] reading, error in
DispatchQueue.main.sync {
guard let image = reading as? UIImage, error == nil else { return }
self?.profileImageView.image = image
picker.dismiss(animated: true, completion: nil)
}
}
}
}
}
I tried to find what`s wrong, but I couldn't
CodePudding user response:
The issue is not in the delegate, the issue is in assigning the value to the label text.
when you initialize the label here
private let nameLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 10, weight: .regular)
label.textColor = UIColor.red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
there is no default value for the label text and its value is nil and when you try to assign the value here by adding a question mark to nameLabel.text?, this means if the value is nil, then don't assign the value to the label text so the value is always nil
func update(name: String, age: String, time: Date) {
nameLabel.text? = name.capitalized
ageLabel.text? = age " years"
}
the solution is to remove the question mark and assign the value to the label.text even if the label.text is nil, like this
func update(name: String, age: String, time: Date) {
nameLabel.text = name.capitalized
ageLabel.text = age " years"
}
and also after that take care of the constraints of the labels
I hope this helps