retrieve information from firebase and set as an image and label in UICollectionView - swift

I am trying to retrieve some data that Is stored in firebase, and allow that Information to be displayed inside of a collection view. Such as profileImageUrl, name label and email label.
I have tried to read the documentation on firebase and apple website, but for some reason, my code returns plain. I don't receive any errors, but my code is not running as expected. When I go to my app's profile view, the only texts that are displayed are the placeholder that I programmatically placed.
let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "users")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
return imageView
}()
let nameLabel: UILabel = {
let label = UILabel()
label.text = "User's Name"
label.font = UIFont.boldSystemFont(ofSize: 18)
label.textColor = GREEN_Theme
return label
}()
let uidLabel: UILabel = {
let label = UILabel()
label.text = "User's uid"
label.font = UIFont.boldSystemFont(ofSize: 16)
label.textColor = GREEN_Theme
return label
}()
let emailLabel: UILabel = {
let label = UILabel()
label.text = "User's email"
label.font = UIFont.boldSystemFont(ofSize: 16)
label.textColor = GREEN_Theme
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
func setupView() {
if Auth.auth().currentUser != nil {
guard let uid = Auth.auth().currentUser?.uid else {
return }
Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else {
return }
let user = CurrentUser(uid: uid, dictionary: dictionary)
self.uidLabel.text = uid
self.nameLabel.text = user.name
self.emailLabel.text = user.email
self.profileImageView.loadImageUsingCacheWithUrlString(user.profileImageUrl)
}, withCancel: { (err) in
print("attempting to load information")
})
self.addSubview(profileImageView)
self.addSubview(nameLabel)
self.addSubview(emailLabel)
self.addSubview(uidLabel)
profileImageView.anchors(top: topAnchor, topPad: 125, bottom: bottomAnchor, bottomPad: 75, left: leftAnchor, leftPad: 20, right: rightAnchor, rightPad: 250, height: 20, width: 20)
nameLabel.anchors(top: profileImageView.bottomAnchor, topPad: -50, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
emailLabel.anchors(top: nameLabel.bottomAnchor, topPad: -80, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 125, height: 20, width: 20)
uidLabel.anchors(top: emailLabel.bottomAnchor, topPad: -40, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
profileImageView.layer.zPosition = 10
nameLabel.layer.zPosition = 10
emailLabel.layer.zPosition = 10
profileImageView.layer.borderWidth = 2.0
profileImageView.layer.cornerRadius = 50
profileImageView.layer.borderWidth = 2.0
profileImageView.layer.borderColor = UIColor.white.cgColor
profileImageView.layer.masksToBounds = true
}
}
I would really appreciate it if someone could help critique what I have, as well as help show me what the correct implementation would look like. Any and all help would be greatly appreciated

There are several things that are not correct.
your cell should not be the one in charge of downloading or doing any network call, leave that to the viewController or even better a separate handler for all the network calls.
Firebase is asynchronous so by the time your data is downloaded all the views have already been set and displayed, that is why you are only seeing your placeholders.
You have a lot of redundant code for checking optionals, this is not much of a problem but it is not needed.
You should really think about changing all this code and separating the different tasks to different handlers. For example, you could create a separate class that controls all the calls to Firebase and returns the values with completion blocks, from the viewController or the collectionView itself ask the network handler to give you the data that you need, pass this data to the cell and let the cell display the data, the cell should only display the data, not download it or ask for networks requests. I cannot write up a complete example for you but I think that if you go around in google you will find a lot of very good examples and tutorials.
Anyway, just to get you started and so you have a look at the mistakes that you have in your code, here is a quick fix for it. Even if it works, don't take for granted that everything is fixed. You should really refactor all the code and separate the different tasks. Hope this helps at least so you can solve the problem of displaying your downloaded data in the cell.
let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "users")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
return imageView
}()
let nameLabel: UILabel = {
let label = UILabel()
label.text = "User's Name"
label.font = UIFont.boldSystemFont(ofSize: 18)
label.textColor = GREEN_Theme
return label
}()
let uidLabel: UILabel = {
let label = UILabel()
label.text = "User's uid"
label.font = UIFont.boldSystemFont(ofSize: 16)
label.textColor = GREEN_Theme
return label
}()
let emailLabel: UILabel = {
let label = UILabel()
label.text = "User's email"
label.font = UIFont.boldSystemFont(ofSize: 16)
label.textColor = GREEN_Theme
return label
}()
// Here you add a variable that is observed for SET, once a set happens bind() will be called and the views will be updated.
var currentUser : CurrentUser? {
didSet {
self.bind()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
//...
}
// setupView() should only add the UI appearance, and in this case it is calling firebase and setting currentUser, but it should not do that. This is what you have to refactor.
func setupView() {
self.addSubview(profileImageView)
self.addSubview(nameLabel)
self.addSubview(emailLabel)
self.addSubview(uidLabel)
profileImageView.anchors(top: topAnchor, topPad: 125, bottom: bottomAnchor, bottomPad: 75, left: leftAnchor, leftPad: 20, right: rightAnchor, rightPad: 250, height: 20, width: 20)
nameLabel.anchors(top: profileImageView.bottomAnchor, topPad: -50, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
emailLabel.anchors(top: nameLabel.bottomAnchor, topPad: -80, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 125, height: 20, width: 20)
uidLabel.anchors(top: emailLabel.bottomAnchor, topPad: -40, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
profileImageView.layer.zPosition = 10
nameLabel.layer.zPosition = 10
emailLabel.layer.zPosition = 10
profileImageView.layer.borderWidth = 2.0
profileImageView.layer.cornerRadius = 50
profileImageView.layer.borderWidth = 2.0
profileImageView.layer.borderColor = UIColor.white.cgColor
profileImageView.layer.masksToBounds = true
guard let user = Auth.auth().currentUser else { return }
let uid = user.uid
let reference = Database.database().reference().child("users").child(uid)
reference.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else { return }
self.currentUser = CurrentUser(uid: uid, dictionary: dictionary)
}, withCancel: { (err) in
print("attempting to load information")
})
}
// This is the method that updates the cell views.
func bind() {
self.uidLabel.text = currentUser.uid
self.nameLabel.text = currentUser.name
self.emailLabel.text = currentUser.email
self.profileImageView.loadImageUsingCacheWithUrlString(currentUser.profileImageUrl)
}

Related

How can I get the contentView to resize when the content changes?

Below you can see two posts, one with an image, and one without. I placed borders around the views to better understand what is happening. I want the posts without images to be sized smaller than images with posts. I attempted to do this by doing the following:
func setupViews() {
backgroundColor = UIColor.white
addSubview(titleLabel)
addSubview(iconImageView)
addSubview(messageTextView)
addSubview(messageImageView)
iconImageView.anchor(top: contentView.topAnchor,
leading: contentView.leadingAnchor,
bottom: nil, trailing: nil,
padding: .init(top: 0, left: 8, bottom: 0, right: 0), size: CGSize(width: 44, height: 44))
titleLabel.anchor(top: contentView.topAnchor,
leading: iconImageView.trailingAnchor,
bottom: nil, trailing: nil,
padding: .init(top: 12, left: 8, bottom: 0, right: 0))
messageTextView.anchor(top: titleLabel.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: nil,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
messageImageViewHeightConstraint = messageImageView.heightAnchor.constraint(equalToConstant: 200)
messageImageViewHeightConstraint.isActive = true
messageImageView.anchor(top: messageTextView.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: contentView.bottomAnchor,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
}
When the posts are loading, I set the messageImageViewHeightConstraint.constant = 0 if the post does not have an image (optionals). This works to collapse the imageView. Unfortunately as you can see the textView expands to cover the remaining space. I don't want this, I want the contentView's intrinsic size to shrink, and I just want the text to expand to meet the content's intrinsic size. How can I do this? Thank you in advance.
Edit: more code for reference
private let iconImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFit
iv.layer.cornerRadius = 10
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
iv.layer.borderWidth = 1
return iv
}()
private let titleLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
label.layer.borderWidth = 1
return label
}()
private let messageTextView: UILabel = {
let labelView = UILabel()
labelView.numberOfLines = 0
labelView.translatesAutoresizingMaskIntoConstraints = false
labelView.font = UIFont.systemFont(ofSize: 14)
labelView.layer.borderWidth = 1
return labelView
}()
private let messageImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 1
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
Edit #2 After following suggestions, here is the new code:
var post: Post?{
didSet{
guard let post = post else {return}
// Adding user's name
let attributedText = NSMutableAttributedString(string: post.author.name + " → " + post.group.name, attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)])
// Adding date and user's first name
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
attributedText.append(NSAttributedString(string: "\n" + dateFormatter.string(from: post.timeCreated), attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12), NSAttributedString.Key.foregroundColor: UIColor(r: 155/255, g: 161/255, b: 171/255)]))
// Increasing Spacing
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 4
attributedText.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))
titleLabel.attributedText = attributedText
// Setting profile image
iconImageView.setImage(for: post.author, setContentMode: .scaleAspectFit)
DispatchQueue.main.async {
self.setupTextAndImageSubviews()
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupDefaultViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupDefaultViews(){
backgroundColor = UIColor.white
addSubview(titleLabel)
addSubview(iconImageView)
iconImageView.anchor(top: contentView.topAnchor, leading: contentView.leadingAnchor, bottom: nil, trailing: nil, padding: .init(top: 0, left: 8, bottom: 0, right: 0), size: CGSize(width: 44, height: 44))
titleLabel.anchor(top: contentView.topAnchor, leading: iconImageView.trailingAnchor, bottom: nil, trailing: nil, padding: .init(top: 12, left: 8, bottom: 0, right: 0))
}
private func setupTextAndImageSubviews() {
addSubview(messageTextView)
var textViewBottomAnchor: NSLayoutYAxisAnchor? = contentView.bottomAnchor
if self.post?.messageImageURL != nil {
textViewBottomAnchor = nil // dont need to anchor text view to bottom if image exists
}
// Setting body text
messageTextView.text = self.post?.body
messageTextView.anchor(top: titleLabel.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: textViewBottomAnchor,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
guard let imageURL = self.post?.messageImageURL else {return} // if no image exists, return, preventing image view from taking extra memory and performance to initialize and calculate constraints
// initialize here instead of globally, so it doesnt take extra memory holding this when no image exists.
let messageImageView: UIImageView = {
let imageView = UIImageView()
imageView.kf.setImage(with: imageURL, placeholder: UIImage(systemName: "person.crop.circle.fill")!.withTintColor(.gray).withRenderingMode(.alwaysOriginal))
imageView.contentMode = .scaleAspectFit
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 1
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
addSubview(messageImageView)
messageImageView.anchor(top: messageTextView.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: contentView.bottomAnchor,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
}
Constraint error:
2021-05-11 13:18:28.184077-0700 GroupUp[8223:1981252] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
"<NSLayoutConstraint:0x283552170 V:[UILabel:0x10598a4e0]-(4)-[UIImageView:0x10881ca00] (active)>",
"<NSLayoutConstraint:0x283550af0 UIImageView:0x10881ca00.bottom == UIView:0x10598a750.bottom (active)>",
"<NSLayoutConstraint:0x28356db80 UILabel:0x10598a4e0.bottom == UIView:0x10598a750.bottom (active)>"
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x283552170 V:[UILabel:0x10598a4e0]-(4)-[UIImageView:0x10881ca00] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
It's because the image view still has an anchor to the top of the text view, and one to the bottom of the content view, so the text view never has an anchor to bottom content view to resize it self and the content view itself, it only has an anchor to the top of the image view.
if you set your imageView's background color to something like red and set the height 2 instead of 0 you would see what's happening.
there are multiple routes you can take to fixing this, the one that I personally think would be the most performance friendly would be to only set the text view and image view and their constraints when you know what data you are dealing with here. image or no image. since right now if you have no image there is an empty imageView inside your view hierarchy just sitting there taking memory (and constraint calculation). and if you were to have some constraints/anchors by default and change them based on new data it would mean re calculating constraints that have already been calculated which would cost performance.
so my approach would look something like:
var data: yourDataModel? {
didSet {
self.updateUI()
}
}
private func updateUI() {
//do all the normal stuff you do with your data here
//run in main thread in case your data is being loaded from the background thread
DispatchQueue.main.async {
self.setupContentSubviews()
}
}
private func setupContentSubviews() {
addSubview(messageTextView)
var textViewBottomAnchor: NSLayoutYAxisAnchor? = contentView.bottomAnchor
if self.data.image != nil {
textViewBottomAnchor = nil // dont need to anchor text view to bottom if image exists
}
messageTextView.anchor(top: titleLabel.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: textViewBottomAnchor,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
guard let image = self.data.image else {return} // if no image exists, return, preventing image view from taking extra memory and performance to initialize and calculate constraints
// initialize here instead of globally, so it doesnt take extra memory holding this when no image exists.
private let messageImageView: UIImageView = {
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 1
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
addSubview(messageImageView)
messageImageViewHeightConstraint = messageImageView.heightAnchor.constraint(equalToConstant: 200)
messageImageViewHeightConstraint.isActive = true
messageImageView.anchor(top: messageTextView.bottomAnchor,
leading: contentView.leadingAnchor,
bottom: contentView.bottomAnchor,
trailing: contentView.trailingAnchor,
padding: .init(top: 4, left: 10, bottom: 0, right: 10))
}
}

UILabel Not Showing Up On View

I just started learning how to code without using storyboards programatically, so please treat me as a beginner... Even though my image shows up on the screen, the label doesn't... I am a little confused as to why this is going on and I appreciate your help. Again, I'm a beginner, do don't mind if its a silly mistake!!!
import UIKit
class LocationRequestController : UIViewController
{
let imageView: UIImageView =
{
let iconImageView = UIImageView()
iconImageView.contentMode = .scaleAspectFit
iconImageView.image = UIImage(named: "blue-pin")
return iconImageView
}()
let allowLocationLabel : UILabel =
{
let label = UILabel()
let attributedText = NSMutableAttributedString(string: "Allow Location\n", attributes: [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 24)])
attributedText.append(NSAttributedString(string: "Please enable location services For The Map To Work!", attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]))
label.numberOfLines = 0
label.textAlignment = .center
label.attributedText = attributedText
return label
}()
override func viewDidLoad()
{
super.viewDidLoad()
configureViewAppearance()
}
func configureViewAppearance()
{
view.backgroundColor = .white
view.addSubview(imageView)
imageView.anchor(top: view.topAnchor, left: nil, bottom: nil, right: nil, paddingTop: 140, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 200, height: 200)
imageView.centerX(inView: view)
view.addSubview(allowLocationLabel)
allowLocationLabel.anchor(top: imageView.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 32, paddingLeft: 32, paddingBottom: 0, paddingRight: 32, width: 0, height: 0)
allowLocationLabel.centerX(inView: view)
}
}
Thanks again!
You just need to add one line label.translatesAutoresizingMaskIntoConstraints
let allowLocationLabel : UILabel =
{
let label = UILabel()
let attributedText = NSMutableAttributedString(string: "Allow Location\n", attributes: [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 24)])
attributedText.append(NSAttributedString(string: "Please enable location services For The Map To Work!", attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]))
label.numberOfLines = 0
label.textAlignment = .center
label.attributedText = attributedText
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
This was the problem:
The text color was automatically set to .white, so that's the reason why it didn't seem to show up! Thanks for your help everyone!

When i try dismiss keyBoard with interactive mode, i have an error for my inputAccessoryView

I've implemented inputAccessoryView with UITextView. I also set collectionView.keyboardDismissMode = .interactive
When i dissmiss keyboard by using interactive mode i have this two error
1) - First responder warning: '<.InputTextView: 0x7f8f54061800; baseClass = UITextView; frame = (8 8; 307 35.5); text = ''; clipsToBounds = YES; gestureRecognizers = ; layer = ; contentOffset: {0, 0}; contentSize: {130, 0}; adjustedContentInset: {0, 0, 0, 0}>' rejected resignFirstResponder when being removed from hierarchy
2) - [UIWindow endDisablingInterfaceAutorotationAnimated:] called on > without matching -beginDisablingInterfaceAutorotation. Ignoring.
Xcode 10 and swift 4
Code For CollectionViewController
lazy var containerView: InputAccesoryView = {
let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
let containerView = InputAccesoryView(frame: frame)
containerView.backgroundColor = UIColor.groupTableViewBackground
containerView.autoresizingMask = .flexibleHeight
containerView.delegate = self
return containerView
}()
override var inputAccessoryView: UIView {
get {
return containerView
}
}
override var canBecomeFirstResponder: Bool {
return true
}
Code for InputAccesoryView
public let inputTextView: InputTextView = {
let textView = InputTextView()
textView.font = UIFont.systemFont(ofSize: 16)
textView.isScrollEnabled = false
textView.textAlignment = .left
textView.layer.cornerRadius = 10
return textView
}()
private lazy var sendButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(named: "send2"), for: .normal)
button.tintColor = .black
button.addTarget(self, action: #selector(handleUploadComment), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureViewComponents()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
return CGSize.zero
}
private func configureViewComponents(){
addSubview(sendButton)
sendButton.setPosition(top: nil, left: nil, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 8, width: 44, height: 0)
sendButton.centerYAnchor.constraint(equalTo: layoutMarginsGuide.centerYAnchor).isActive = true
addSubview(inputTextView)
inputTextView.setPosition(top: topAnchor, left: leftAnchor, bottom: layoutMarginsGuide.bottomAnchor, right: sendButton.leftAnchor, paddingTop: 8, paddingLeft: 8, paddingBottom: 8, paddingRight: 8, width: 0, height: 0)
let separatorView = UIView()
separatorView.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
addSubview(separatorView)
separatorView.setPosition(top: topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0.5)
}
func clearCommentTextView() {
inputTextView.text = nil
inputTextView.placeHolder.isHidden = false
}

UIPopoverPresentationController programmatically created fills the screen

The popup that I am creating programmatically fills the screen. As you can see from the example code, I have tried many ways to limit its size, but none are working. Also, the delegate methods are not being called. Any ideas? I have used CALayer successfully in the past for this kind of thing, but thought this would be simpler - maybe not.
#objc func touchDownHandler(sender: UISlider) {
let popoverController = UIViewController()
popoverController.view.backgroundColor = .red
popoverController.view.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
let textLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
textLabel.text = "Hello World"
textLabel.backgroundColor = .green
popoverController.view.addSubview(textLabel)
popoverController.modalPresentationStyle = UIModalPresentationStyle.popover
popoverController.preferredContentSize = CGSize(width: 200, height: 200)
if let popoverPresentation = popoverController.popoverPresentationController {
popoverPresentation.delegate = self
popoverPresentation.sourceRect = sender.frame
popoverPresentation.popoverLayoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 210, right: 210)
popoverPresentation.backgroundColor = .blue
self.controller.present(popoverController, animated: true, completion: {
print("pop over is visible")
})
}
}
Keep in mind that, as per Apple documentation, "In a horizontally compact environment, the .popover option behaves the same as UIModalPresentationStyle.fullScreen."
https://developer.apple.com/documentation/uikit/uimodalpresentationstyle/popover

my Signup controller won't display email text fields.

I have been trying to programmatically create two separate view controllers in which I have a login, and sign up view controller. While my initial view controller, Login allows me to see the email/password text field, my sign up controller does not. I have plugged in the correct information however when I run my application, it is blank. I will post my code below, can anyone help me solve this issue?
let emailTextField: UITextField = {
let e = UITextField()
let attributedPlaceholder = NSAttributedString(string: "Email", attributes:
[NSAttributedStringKey.foregroundColor : UIColor.white])
e.textColor = .white
e.attributedPlaceholder = attributedPlaceholder
e.setBottomBorder(backGroundColor: GREEN_Theme, borderColor: .white)
return e
}()
let passwordTextField: UITextField = {
let p = UITextField()
let attributedPlaceholder = NSAttributedString(string: "Password", attributes: [NSAttributedStringKey.foregroundColor : UIColor.white])
p.textColor = .white
p.isSecureTextEntry = true
p.attributedPlaceholder = attributedPlaceholder
p.setBottomBorder(backGroundColor: GREEN_Theme, borderColor: .white)
return p
}()
override func viewDidLoad (){
super.viewDidLoad()
view.backgroundColor = GREEN_Theme
func setupFileComponents() {
setupEmailField()
setupPasswordField()
}
func setupEmailField() {
view.addSubview(emailTextField)
emailTextField.anchors(top: nil, topPad: 0, bottom: nil, bottomPad: 0, left: view.leftAnchor, leftPad: 24, right: view.rightAnchor, rightPad: 24, height: 30, width: 0)
emailTextField.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
func setupPasswordField() {
view.addSubview(passwordTextField)
passwordTextField.anchors(top: emailTextField.bottomAnchor, topPad: 8, bottom: nil, bottomPad: 0, left: emailTextField.leftAnchor, leftPad: 0, right: emailTextField.rightAnchor, rightPad: 0, height: 30, width: 0)
}
Thank you in advance.
You should move setupFileComponents, setupEmailField, setupPasswordField out of viewDidLoad then you have to add te calls in viewDidLoad like that:
override func viewDidLoad (){
super.viewDidLoad()
view.backgroundColor = GREEN_Theme
setupFileComponents()
setupEmailField()
setupPasswordField()
}