特定のVCに遷移できない
Q&A
Closed
解決したいこと
TabBarController
をrootVCとし、ログインしていなければWelcomeViewController
へ遷移し、そこで新規登録であればサインアップボタンをタップしてSignUpViewController
へ遷移します。SignUpViewContoller
では、ユーザー作成が成功したタイミングで、ユーザー情報を登録するEditViewContoller
へ遷移させたいのですが、この処理が上手くいきません。
試しにrootVCをEditVieController
に設定してみると真っ白に表示され、まもなくクラッシュしました。EditViewController
が表示されない問題とは関係ないかもしれませんが、その際に表示されたデバッグのメッセージとスクショを添付します。
同時にMyAccountViewController
という別のファイル内にThread 1: EXC_BAD_ACCESS (code=2, address=0x16c623cc0)
というエラーが表示されています。
長くて申し訳ありませんがほとんど省略せず、各VCのコードも添付します。
発生している問題・エラー
warning: Module "/usr/lib/system/libsystem_kernel.dylib" uses triple "arm64-apple-macosx14.1.0", which is not compatible with the target triple "arm64-apple-ios17.0.0-simulator". Enabling per-module Swift scratch context.
Thread 1: EXC_BAD_ACCESS (code=2, address=0x16c623cc0)
該当するソースコード
<SignUpViewController>
import UIKit
import SnapKit
import FirebaseAuth
import PKHUD
class SignUpViewController: UITableViewController, SignUpViewCellDelegate {
let screenWidth = UIScreen.main.bounds.width
override func viewDidLoad() {
super.viewDidLoad()
tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
tableView.delaysContentTouches = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(SignUpViewCell.self, forCellReuseIdentifier: "signUpViewCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 600
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "signUpViewCell") as! SignUpViewCell
cell.signUpViewCellDelegate = self
return cell
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false
}
func signUpButtonDelegate(_ sender: SignUpViewCell) {
let signUpViewCell = sender
if let artistName = signUpViewCell.artistNameTextField.text, let mailAddress = signUpViewCell.mailAddressTextField.text, let password = signUpViewCell.passwordTextField.text {
if artistName.isEmpty || mailAddress.isEmpty || password.isEmpty {
HUD.flash(.labeledError(title: "Sign Up Failed", subtitle: "必要項目を入力してください"), delay: 1)
return
}
Auth.auth().createUser(withEmail: mailAddress, password: password) {authResult, error in
if error != nil {
HUD.flash(.labeledError(title: "Sign Up Failed", subtitle: "ユーザー作成に失敗しました"), delay: 1)
return
}
HUD.flash(.labeledError(title: "Sign Up Successful!", subtitle: ""), delay: 1)
let currentUser = Auth.auth().currentUser
if let user = currentUser {
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = artistName
changeRequest.commitChanges {error in
if error != nil {
HUD.flash(.labeledError(title: "Sign Up Failed", subtitle: "アーティスト名の設定に失敗しました"), delay: 1)
return
}
let editViewController = EditViewController()
editViewController.modalPresentationStyle = .fullScreen
self.present(editViewController, animated: true, completion: nil)
}
}
self.dismiss(animated: true)
}
} else {
HUD.flash(.labeledError(title: "Error", subtitle: "必要項目を入力してください"), delay: 1)
return
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
tableView.endEditing(true)
}
}
<EditViewController>
import UIKit
import SnapKit
import PKHUD
import CropViewController
import FirebaseAuth
import FirebaseFirestore
import FirebaseStorage
import FirebaseStorageUI
class EditViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CropViewControllerDelegate, EditViewCellDelegate {
let screenWidth = UIScreen.main.bounds.width
let editViewCell = EditViewCell()
let myAccountViewController = MyAccountViewController()
let myAccountViewCell = MyAccountViewCell()
override func viewDidLoad() {
super.viewDidLoad()
tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
tableView.delaysContentTouches = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(EditViewCell.self, forCellReuseIdentifier: "editViewCell")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
currentData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 1000
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "editViewCell") as! EditViewCell
cell.editViewCellDelegate = self
return cell
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false
}
func iconImageViewDelegate() {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .photoLibrary
self.present(pickerController, animated: true, completion: nil)
}
}
func registerButtonDelegate() {
let user = Auth.auth().currentUser
let uid = Auth.auth().currentUser?.uid
let imageRef = Storage.storage().reference().child(Const.ImagePath).child(uid! + ".jpg")
let userRef = Firestore.firestore().collection(Const.UserPath).document(uid!)
let iconData = editViewCell.iconImageView.image?.jpegData(compressionQuality: 1.0)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
HUD.show(.progress)
imageRef.putData(iconData!, metadata: metadata) { [self] (metadata, error) in
if error != nil {
HUD.flash(.labeledError(title: "Upload Failed", subtitle: ""), delay: 1)
return
}
let userDic = [
"artistName": editViewCell.artistNameTextField.text!,
"birthday": editViewCell.birthdayTextField.text!,
"myBase": editViewCell.myBaseTextField.text!,
"myPart": editViewCell.myPartTextField.text!,
"myGenre": editViewCell.myGenreTextField.text!,
"url": editViewCell.urlTextField.text!,
"introduction": editViewCell.introductionTextView.text!,
"ivtPart": editViewCell.ivtPartTextField.text!,
"ivtTitle": editViewCell.ivtTitleTextField.text!,
"ivtContent": editViewCell.ivtContentTextView.text!,
] as [String : Any]
userRef.setData(userDic as [String : Any]) { error in
if error != nil {
HUD.flash(.labeledError(title: "Upload Failed", subtitle: ""), delay: 1)
return
}
HUD.flash(.labeledError(title: "Upload Successful!", subtitle: ""), delay: 1)
}
if let user = user {
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = editViewCell.artistNameTextField.text
changeRequest.commitChanges { error in
if error != nil {
HUD.flash(.labeledError(title: "Register Failed.", subtitle: ""), delay: 1)
return
}
HUD.flash(.labeledError(title: "Register Successful!", subtitle: ""), delay: 1)
}
}
}
HUD.hide()
self.dismiss(animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if info[.originalImage] != nil {
let image = info[.originalImage] as! UIImage
let cropViewController = CropViewController(croppingStyle: .default, image: image)
cropViewController.delegate = self
cropViewController.customAspectRatio = editViewCell.iconImageView.frame.size
cropViewController.aspectRatioPickerButtonHidden = true
cropViewController.resetAspectRatioEnabled = false
cropViewController.rotateButtonsHidden = true
cropViewController.cropView.cropBoxResizeEnabled = false
picker.dismiss(animated: true) {
self.present(cropViewController, animated: true, completion: nil)
}
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
editViewCell.iconImageView.image = image
cropViewController.dismiss(animated: true, completion: nil)
}
func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
cropViewController.dismiss(animated: true, completion: nil)
}
func currentData() {
let uid = Auth.auth().currentUser?.uid
let displayName = Auth.auth().currentUser?.displayName
let imageRef = Storage.storage().reference().child(Const.ImagePath).child(uid! + ".jpg")
editViewCell.iconImageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
editViewCell.iconImageView.sd_setImage(with: imageRef)
let userRef = Firestore.firestore().collection(Const.UserPath).document(uid!)
userRef.getDocument { [self] (document, error) in
if error != nil {
HUD.flash(.labeledError(title: "Error.", subtitle: ""), delay: 1)
}
if let document = document, document.exists {
let userDic = document.data()
editViewCell.artistNameTextField.text = displayName
editViewCell.birthdayTextField.text = userDic!["birthday"] as? String
editViewCell.myBaseTextField.text = userDic!["myBase"] as? String
editViewCell.myPartTextField.text = userDic!["myPart"] as? String
editViewCell.myGenreTextField.text = userDic!["myGenre"] as? String
editViewCell.urlTextField.text = userDic!["url"] as? String
editViewCell.introductionTextView.text = userDic!["introduction"] as? String
editViewCell.ivtPartTextField.text = userDic!["ivtPart"] as? String
editViewCell.ivtTitleTextField.text = userDic!["ivtTitle"] as? String
editViewCell.ivtContentTextView.text = userDic!["ivtContent"] as? String
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
tableView.endEditing(true)
}
}
<EditViewCell>
import UIKit
import SnapKit
import Firebase
protocol EditViewCellDelegate: AnyObject {
func iconImageViewDelegate()
func registerButtonDelegate()
}
class EditViewCell: UITableViewCell, UITextFieldDelegate, UITextViewDelegate, UIPickerViewDelegate, UIPickerViewDataSource {
weak var editViewCellDelegate: EditViewCellDelegate? = nil
let iconImageView = UIImageView()
let profileLabel = UILabel()
let artistNameLabel = UILabel()
let artistNameTextField = UITextField()
let birthdayLabel = UILabel()
let birthdayTextField = UITextField()
let myBaseLabel = UILabel()
let myBaseTextField = UITextField()
let myPartLabel = UILabel()
let myPartTextField = UITextField()
let myGenreLabel = UILabel()
let myGenreTextField = UITextField()
let urlLabel = UILabel()
let urlTextField = UITextField()
let introductionLabel = UILabel()
let introductionTextView = UITextView()
let invitationlabel = UILabel()
let ivtPartLabel = UILabel()
let ivtPartTextField = UITextField()
let ivtTitleLabel = UILabel()
let ivtTitleTextField = UITextField()
let ivtContentLabel = UILabel()
let ivtContentTextView = UITextField()
let registerButton = UIButton()
let toolBarForBirthday = UIToolbar()
let spaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneItemForBirthday = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneForBirthday))
let datePicker = UIDatePicker()
let dateFormatter = DateFormatter()
let toolBarForPickerView = UIToolbar()
let doneItemForPickerView = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneForPickerView))
let pickerViewForMyBase = UIPickerView()
let pickerViewForMyPart = UIPickerView()
let pickerViewForMyGenre = UIPickerView()
let pickerViewForIvtPart = UIPickerView()
let dataForBase = ["北海道" //略]
let dataForPart = ["Vocal" //略]
let dataForGenre = ["Pop" //略]
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
artistNameTextField.delegate = self
birthdayTextField.delegate = self
myBaseTextField.delegate = self
myPartTextField.delegate = self
myGenreTextField.delegate = self
introductionTextView.delegate = self
ivtPartTextField.delegate = self
ivtTitleTextField.delegate = self
ivtContentTextView.delegate = self
pickerViewForMyBase.delegate = self
pickerViewForMyBase.dataSource = self
pickerViewForMyPart.delegate = self
pickerViewForMyPart.dataSource = self
pickerViewForMyGenre.delegate = self
pickerViewForMyGenre.dataSource = self
pickerViewForIvtPart.delegate = self
pickerViewForIvtPart.dataSource = self
setupSubviews()
setupDatePicker()
setupPickerView()
iconImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(iconImageViewTapped)))
registerButton.addTarget(self, action: #selector(handleRegisterButton(_:)), for: .touchUpInside)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
iconImageView.image = UIImage(systemName: "person")
iconImageView.isUserInteractionEnabled = true
profileLabel.text = "プロフィール"
profileLabel.font = UIFont.boldSystemFont(ofSize: 20)
profileLabel.adjustsFontSizeToFitWidth = true
profileLabel.textAlignment = .left
artistNameLabel.text = "アーティスト名"
artistNameLabel.font = UIFont.systemFont(ofSize: 18)
artistNameLabel.adjustsFontSizeToFitWidth = true
artistNameLabel.textAlignment = .left
artistNameTextField.addBorderBottom(height: 2, color: .cyan)
artistNameTextField.text = Auth.auth().currentUser?.displayName
artistNameTextField.font = UIFont.systemFont(ofSize: 18)
artistNameTextField.clearButtonMode = .whileEditing
birthdayLabel.text = "生年月日"
birthdayLabel.font = UIFont.systemFont(ofSize: 18)
birthdayLabel.adjustsFontSizeToFitWidth = true
birthdayLabel.textAlignment = .left
birthdayTextField.addBorderBottom(height: 2, color: .cyan)
birthdayTextField.font = UIFont.systemFont(ofSize: 18)
myBaseLabel.text = "拠点"
myBaseLabel.font = UIFont.systemFont(ofSize: 18)
myBaseLabel.adjustsFontSizeToFitWidth = true
myBaseLabel.textAlignment = .left
myBaseTextField.addBorderBottom(height: 2, color: .cyan)
myBaseTextField.font = UIFont.systemFont(ofSize: 18)
myPartLabel.text = "パート"
myPartLabel.font = UIFont.systemFont(ofSize: 18)
myPartLabel.adjustsFontSizeToFitWidth = true
myPartLabel.textAlignment = .left
myPartTextField.addBorderBottom(height: 2, color: .cyan)
myPartTextField.font = UIFont.systemFont(ofSize: 18)
myGenreLabel.text = "ジャンル"
myGenreLabel.font = UIFont.systemFont(ofSize: 18)
myGenreLabel.adjustsFontSizeToFitWidth = true
myGenreLabel.textAlignment = .left
myGenreTextField.addBorderBottom(height: 2, color: .cyan)
myGenreTextField.font = UIFont.systemFont(ofSize: 18)
introductionLabel.text = "自己紹介"
introductionLabel.font = UIFont.systemFont(ofSize: 18)
introductionLabel.adjustsFontSizeToFitWidth = true
introductionLabel.textAlignment = .left
introductionTextView.font = UIFont.systemFont(ofSize: 12)
introductionTextView.layer.cornerRadius = 5
introductionTextView.layer.borderWidth = 1
introductionTextView.layer.borderColor = UIColor.cyan.cgColor
invitationlabel.text = "募集"
invitationlabel.font = UIFont.boldSystemFont(ofSize: 20)
invitationlabel.adjustsFontSizeToFitWidth = true
invitationlabel.textAlignment = .left
ivtPartLabel.text = "パート"
ivtPartLabel.font = UIFont.systemFont(ofSize: 18)
ivtPartLabel.adjustsFontSizeToFitWidth = true
ivtPartLabel.textAlignment = .left
ivtPartTextField.addBorderBottom(height: 2, color: .cyan)
ivtPartTextField.font = UIFont.systemFont(ofSize: 18)
ivtTitleLabel.text = "募集タイトル"
ivtTitleLabel.font = UIFont.systemFont(ofSize: 18)
ivtTitleLabel.adjustsFontSizeToFitWidth = true
ivtTitleLabel.textAlignment = .left
ivtTitleTextField.addBorderBottom(height: 2, color: .cyan)
ivtTitleTextField.font = UIFont.systemFont(ofSize: 18)
ivtContentLabel.text = "募集内容"
ivtContentLabel.font = UIFont.systemFont(ofSize: 18)
ivtContentLabel.adjustsFontSizeToFitWidth = true
ivtContentLabel.textAlignment = .left
ivtContentTextView.font = UIFont.systemFont(ofSize: 12)
ivtContentTextView.layer.cornerRadius = 5
ivtContentTextView.layer.borderWidth = 1
ivtContentTextView.layer.borderColor = UIColor.cyan.cgColor
registerButton.setTitle("登録", for: .normal)
registerButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
registerButton.titleLabel?.adjustsFontSizeToFitWidth = true
registerButton.backgroundColor = UIColor(hex: "FF77FF")
registerButton.layer.borderWidth = 2
registerButton.layer.borderColor = UIColor(hex: "FF77FF").cgColor
registerButton.layer.cornerRadius = registerButton.frame.height / 2
registerButton.layer.masksToBounds = true
}
func setupSubviews() {
contentView.addSubview(iconImageView)
contentView.addSubview(profileLabel)
contentView.addSubview(artistNameLabel)
contentView.addSubview(artistNameTextField)
contentView.addSubview(birthdayLabel)
contentView.addSubview(birthdayTextField)
contentView.addSubview(myBaseLabel)
contentView.addSubview(myBaseTextField)
contentView.addSubview(myPartLabel)
contentView.addSubview(myPartTextField)
contentView.addSubview(myGenreLabel)
contentView.addSubview(myGenreTextField)
contentView.addSubview(urlLabel)
contentView.addSubview(urlTextField)
contentView.addSubview(introductionLabel)
contentView.addSubview(introductionTextView)
contentView.addSubview(invitationlabel)
contentView.addSubview(ivtPartLabel)
contentView.addSubview(ivtPartTextField)
contentView.addSubview(ivtTitleLabel)
contentView.addSubview(ivtTitleTextField)
contentView.addSubview(ivtContentLabel)
contentView.addSubview(ivtContentTextView)
contentView.addSubview(registerButton)
iconImageView.snp.makeConstraints {
$0.size.equalTo(contentView.frame.size.width)
$0.top.equalTo(40)
$0.centerX.equalToSuperview()
}
profileLabel.snp.makeConstraints {
$0.height.equalTo(60)
$0.top.equalTo(iconImageView.snp.bottom).offset(40)
$0.leading.equalToSuperview().offset(15)
$0.trailing.equalToSuperview().offset(-15)
}
artistNameLabel.snp.makeConstraints {
$0.width.equalTo(120)
$0.height.equalTo(40)
$0.top.equalTo(profileLabel.snp.bottom).offset(20)
$0.leading.equalToSuperview().offset(20)
}
artistNameTextField.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(artistNameLabel)
$0.leading.equalTo(artistNameLabel.snp.trailing).offset(10)
$0.trailing.equalToSuperview().offset(-20)
}
birthdayLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(artistNameLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
birthdayTextField.snp.makeConstraints {
$0.top.equalTo(birthdayLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(birthdayLabel)
}
myBaseLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(birthdayLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
myBaseTextField.snp.makeConstraints {
$0.top.equalTo(myBaseLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(myBaseLabel)
}
myPartLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(myBaseLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
myPartTextField.snp.makeConstraints {
$0.top.equalTo(myPartLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(myPartLabel)
}
myGenreLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(myPartLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
myGenreTextField.snp.makeConstraints {
$0.top.equalTo(myGenreLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(myGenreLabel)
}
urlLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(myGenreLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
urlTextField.snp.makeConstraints {
$0.top.equalTo(urlLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(urlLabel)
}
introductionLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(urlLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
introductionTextView.snp.makeConstraints {
$0.height.equalTo(150)
$0.top.equalTo(introductionLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
}
invitationlabel.snp.makeConstraints {
$0.height.equalTo(profileLabel)
$0.top.equalTo(introductionTextView.snp.bottom).offset(40)
$0.leading.equalTo(profileLabel)
$0.trailing.equalTo(profileLabel)
}
ivtPartLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(invitationlabel.snp.bottom).offset(20)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
ivtPartTextField.snp.makeConstraints {
$0.top.equalTo(ivtPartLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(ivtPartLabel)
}
ivtTitleLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(ivtPartLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
ivtTitleTextField.snp.makeConstraints {
$0.top.equalTo(ivtTitleLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
$0.bottom.equalTo(ivtTitleLabel)
}
ivtContentLabel.snp.makeConstraints {
$0.height.equalTo(artistNameLabel)
$0.top.equalTo(ivtTitleLabel.snp.bottom).offset(10)
$0.leading.equalTo(artistNameLabel)
$0.trailing.equalTo(artistNameLabel)
}
ivtContentTextView.snp.makeConstraints {
$0.height.equalTo(200)
$0.top.equalTo(ivtContentLabel)
$0.leading.equalTo(artistNameTextField)
$0.trailing.equalTo(artistNameTextField)
}
registerButton.snp.makeConstraints {
$0.width.equalToSuperview().multipliedBy(0.4)
$0.height.equalTo(25)
$0.top.equalTo(ivtContentTextView.snp.bottom).offset(-60)
$0.centerX.equalToSuperview()
}
}
func setupDatePicker() {
datePicker.datePickerMode = .date
datePicker.locale = Locale(identifier: "ja_JP")
toolBarForBirthday.sizeToFit()
toolBarForBirthday.setItems([spaceItem, doneItemForBirthday], animated: true)
birthdayTextField.inputAccessoryView = toolBarForBirthday
birthdayTextField.inputView = datePicker
}
func setupPickerView() {
toolBarForPickerView.sizeToFit()
toolBarForPickerView.setItems([spaceItem, doneItemForPickerView], animated: true)
myBaseTextField.inputAccessoryView = toolBarForPickerView
myBaseTextField.inputView = pickerViewForMyBase
myPartTextField.inputAccessoryView = toolBarForPickerView
myPartTextField.inputView = pickerViewForMyPart
myGenreTextField.inputAccessoryView = toolBarForPickerView
myGenreTextField.inputView = pickerViewForMyGenre
ivtPartTextField.inputAccessoryView = toolBarForPickerView
ivtPartTextField.inputView = pickerViewForIvtPart
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.endEditing(true)
}
@objc func doneForBirthday() {
dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
dateFormatter.locale = Locale.current
birthdayTextField.text = dateFormatter.string(from: datePicker.date)
self.endEditing(true)
}
@objc func doneForPickerView() {
self.endEditing(true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerViewForMyBase {
return dataForBase.count
} else if pickerView == pickerViewForMyPart {
return dataForPart.count
} else if pickerView == pickerViewForMyGenre {
return dataForGenre.count
} else if pickerView == pickerViewForIvtPart {
return dataForPart.count
}
return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pickerViewForMyBase {
return dataForBase[row]
} else if pickerView == pickerViewForMyPart {
return dataForPart[row]
} else if pickerView == pickerViewForMyGenre {
return dataForGenre[row]
} else if pickerView == pickerViewForIvtPart {
return dataForPart[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == pickerViewForMyBase {
myBaseTextField.text = dataForBase[row]
} else if pickerView == pickerViewForMyPart {
myPartTextField.text = dataForPart[row]
} else if pickerView == pickerViewForMyGenre {
myGenreTextField.text = dataForGenre[row]
} else if pickerView == pickerViewForIvtPart {
ivtPartTextField.text = dataForPart[row]
}
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.text == "200文字以内" {
textView.text = nil
textView.textColor = .darkText
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.textColor = .lightGray
textView.text = "200文字以内"
}
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return textView.text.count + (text.count - range.length) <= 200
}
@objc func iconImageViewTapped () {
editViewCellDelegate?.iconImageViewDelegate()
}
@objc func handleRegisterButton(_ sender: UIButton) {
editViewCellDelegate?.registerButtonDelegate()
}
}
<MyAccountViewController>
import UIKit
import SnapKit
import PKHUD
import FirebaseAuth
import FirebaseFirestore
import FirebaseStorage
import FirebaseStorageUI
class MyAccountViewController: UITableViewController, MyAccountViewCellDelegate {
let iconImageView = UIImageView()
let editButton = UIButton()
let myAccountViewCell = MyAccountViewCell()
var artistName: String!
var birthday: String!
var startingFrame : CGRect!
var endingFrame : CGRect!
override func viewDidLoad() {
super.viewDidLoad()
tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
tableView.delaysContentTouches = false
tableView.backgroundColor = .clear
tableView.delegate = self
tableView.dataSource = self
setupSubviews()
configureSizes()
tableView.register(MyAccountViewCell.self, forCellReuseIdentifier: "myAccountViewCell")
editButton.addTarget(self, action: #selector(handleEditButton(_:)), for: .touchUpInside)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getData()
togglePostSwitch()
birthdayToAge()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myAccountViewCell") as! MyAccountViewCell
cell.backgroundColor = .clear
cell.myAccountViewCellDelegate = self
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
return screenWidth + screenHeight - 95
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false
}
func setupSubviews() {
let defaultIconImage = UIImage(systemName: "person")
iconImageView.contentMode = .scaleAspectFit
iconImageView.image = defaultIconImage
editButton.setTitle("編集", for: .normal)
editButton.titleLabel?.font = UIFont.systemFont(ofSize: 17)
editButton.titleLabel?.adjustsFontSizeToFitWidth = true
editButton.backgroundColor = UIColor(hex: "FF77FF")
editButton.layer.cornerRadius = editButton.frame.size.height / 2
editButton.layer.masksToBounds = true
tableView.backgroundView = iconImageView
tableView.addSubview(editButton)
iconImageView.snp.makeConstraints {
$0.width.height.equalTo(tableView.frame.width)
$0.top.equalToSuperview()
$0.leading.equalToSuperview()
}
editButton.snp.makeConstraints {
$0.width.equalTo(tableView.frame.width * 0.6)
$0.height.equalTo(30)
$0.bottom.equalToSuperview().offset(-50)
$0.centerX.equalToSuperview()
}
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) && self.editButton.isHidden {
self.editButton.isHidden = false
self.editButton.frame = startingFrame
UIView.animate(withDuration: 1.0) {
self.editButton.frame = self.endingFrame
}
}
}
func configureSizes() {
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
startingFrame = CGRect(x: 0, y: screenHeight + 100, width: screenWidth, height: 100)
endingFrame = CGRect(x: 0, y: screenHeight - 100, width: screenWidth, height: 100)
}
func getData() {
let uid = Auth.auth().currentUser?.uid
let imageRef = Storage.storage().reference().child(Const.ImagePath).child(uid! + ".jpg")
iconImageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
iconImageView.sd_setImage(with: imageRef)
let userRef = Firestore.firestore().collection(Const.UserPath).document(uid!)
userRef.getDocument { (document, error) in
if error != nil {
HUD.flash(.labeledError(title: "Error.", subtitle: ""), delay: 1)
}
if let document = document, document.exists {
let userDic = document.data()
self.myAccountViewCell.baseLabel.text = userDic!["myBase"] as? String
self.myAccountViewCell.partLabel.text = userDic!["myPart"] as? String
self.myAccountViewCell.genreLabel.text = userDic!["myGenre"] as? String
self.myAccountViewCell.ivtPartLabel.text = userDic!["ivtPart"] as? String
self.myAccountViewCell.ivtTitleLabel.text = userDic!["ivtTitle"] as? String
self.myAccountViewCell.ivtContentLabel.text = userDic!["ivtContent"] as? String
self.myAccountViewCell.introductionLabel.text = userDic!["introduction"] as? String
self.myAccountViewCell.urlLabel.text = userDic!["url"] as? String
if let birthday = userDic!["birthday"] as? String {
let displayName = Auth.auth().currentUser?.displayName
let dateFormatter = DateFormatter()
let date = dateFormatter.date(from: birthday)
let components = Calendar.current.dateComponents(in: TimeZone.current, from: date!)
let year = components.year
let month = components.month
let day = components.day
var ageInt: Int
let birthdate = DateComponents(year: year, month: month, day: day)
let calendar = Calendar.current
let now = calendar.dateComponents([.year, .month, .day], from: Date())
let ageComponents = calendar.dateComponents([.year], from: birthdate, to: now)
ageInt = ageComponents.year!
let ageStr = String(ageInt)
let nameAge = displayName! + " " + ageStr
self.myAccountViewCell.nameAgeLabel.text = nameAge
}
} else {
HUD.flash(.labeledError(title: "No Documents.", subtitle: ""), delay: 1)
}
}
}
func togglePostSwitch() {
let uid = Auth.auth().currentUser?.uid
let postRef = Firestore.firestore().collection(Const.PostPath).document(uid!)
postRef.getDocument { (document, error) in
if error != nil {
HUD.flash(.labeledError(title: "Error.", subtitle: ""), delay: 1)
}
if let document = document, document.exists {
self.myAccountViewCell.postSwitch.isOn = true
} else {
self.myAccountViewCell.postSwitch.isOn = false
}
}
}
func birthdayToAge() {
let dateFormatter = DateFormatter()
let date = dateFormatter.date(from: birthday)
let components = Calendar.current.dateComponents(in: TimeZone.current, from: date!)
let year = components.year
let month = components.month
let day = components.day
var ageInt: Int
let birthdate = DateComponents(year: year, month: month, day: day)
let calendar = Calendar.current
let now = calendar.dateComponents([.year, .month, .day], from: Date())
let ageComponents = calendar.dateComponents([.year], from: birthdate, to: now)
ageInt = ageComponents.year!
let ageStr = String(ageInt)
let nameAge = artistName + " " + ageStr
myAccountViewCell.nameAgeLabel.text = nameAge
}
@objc func handleEditButton(_ sender: UIButton) {
let editViewController = EditViewController()
editViewController.modalPresentationStyle = .fullScreen
self.present(editViewController, animated: true, completion: nil)
}
func backButtonDelegate() {
self.dismiss(animated: true)
}
func settingButtonDelegate() {
let settingViewController = SettingViewController()
settingViewController.modalPresentationStyle = .fullScreen
self.present(settingViewController, animated: true, completion: nil)
}
}