This question already has an answer here:

I have 2 labels: errorLabel, where errors are stored lblUsernameGlobal, where Usernames are stored

Master Page File:

                <asp:LoginView runat="server" ViewStateMode="Disabled">
                    <AnonymousTemplate>
                        <ul class="nav navbar-nav navbar-right">
                            <asp:DropDownList ID="lstSprache" AutoPostBack="true" Visible="true" runat="server" >
                                <asp:ListItem>Deutsch</asp:ListItem>
                                <asp:ListItem>Berndeutsch</asp:ListItem>
                                <asp:ListItem>Englisch</asp:ListItem>
                            </asp:DropDownList>
                            <li><asp:Label ID = "lblUsernameGlobal" runat = "server" Text=""></asp:Label></li> {...}
            <asp:Label ID="errorLabel" runat="server" Text=""></asp:Label>
            <p>&copy; <%: DateTime.Now.Year %></p>
        </div>
    </div>
</form>

Login.aspx.cs:

protected void btnLogin_Click(object sender, EventArgs e)
    {
        username = txtBenutzername.Text;
        passwort = txtPasswort.Text;
        Label errorLabel = (Label)Master.FindControl("errorLabel");
        Label lblUsernameGlobal = (Label)Master.FindControl("lblUsernameGlobal");
        if (lblUsernameGlobal != null)
        {
            lblUsernameGlobal.Text = "BlaBla";
        }
        else
        {
            try
            {
                lblUsernameGlobal.Text = "BlaBla";
                errorLabel.Text = "Label nicht gefunden";
            }
            catch (Exception ex)
            {
                errorLabel.Text = ex.Message;
            }
        }
        if (username != "" && passwort != "")
        {
            //errorLabel.Text = dbConnect.SelectBenutzerSpecific(username, passwort);
            //lblUsernameGlobal.Text = username;
            //errorLabel.Text = username;
        }
        else
        {
            errorLabel.Text = "Invalid!";
        }
    }

After loads and loads of testing I have yet to find out, why the lblUsernameGlobal doesn't work. I can work with the errorlabel, but as soon as I try to reference the lblUsernameGlobal I get a NullReference. How can I reference lblUsernameGlobal without getting a NullReference?

I did some research but I could not find an appropriate answer regarding the following question.

I don't use the interface builder to generate my views so every control is defined programmatically like so :

let loginButton: UIButton = {
  let button = UIBUtton()
  button.setTitle("Title", forState: .Normal)
  // adding some properties to my button
  return button
}()

Then I add it to the view of my ViewController like that :

self.view.addSubview(loginButton)

And I add some constraints with the Visual Format Language

For example :

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat
_("V:|[v0(25)]|", options:NSLayoutFormatOptions(), metrics: nil, 
_views: ["v0":loginButton]))

It works really well and I prefer it that way(over the IB) but the main issue is that I end up with really big ViewController classes as I define every controls in the ViewControllers classes.

I guess I should have all the controls declarations, constraints,... in a separate file but I can't find how to do that.

I tried to create a separate class, for example LoginView, which contains all the controls, and a function setupViews(superView: UIView) that adds subviews to the superView parameter and specify constraints. Then in the viewDidLoad() method of my ViewController, I instantiate this class (LoginView) and execute the setupView(superView: self.view). It looks like this :

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let loginView = LoginView()
        loginView.setupViews(self.view)

    }
}

I am pretty sure this is not the way to go. It also causes problems when I try to addTarget to some of my controls.

My question, what is the best way to do it, following the MVC pattern. Thank you very much !

EDIT 1 :

As asked in the comments, here is the implementation of the LoginView class (I only kept few controls/constraints to keep it short but it is the same process for every other one)

import UIKit

class LoginView {

 let superView: UIView?

 init(tempSuperView: UIView){
  superView = tempSuperView
 }

 let usernameTextField: UITextField = {
  let textField = UITextField()
  textField.translatesAutoresizingMaskIntoConstraints = false
  textField.textColor = UIColor.whiteColor()

  return textField
 }()

 let loginButton: UIButton = {
  let button = UIButton()
  button.translatesAutoresizingMaskIntoConstraints = false
  button.setTitle("Login", forState: .Normal)

 return button
 }()

 //some more controls definition

 func setupViews() -> Void {

 superView!.addSubview(usernameTextField)
 superView!.addSubview(loginButton)

 superView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat
_("V:|-150-[v0(50)]", options:NSLayoutFormatOptions(), metrics: nil, 
_views: ["v0":usernameTextField]))
 superView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat
_("H:|-150-[v0(25)]", options:NSLayoutFormatOptions(), metrics: nil, 
_views: ["v0":usernameTextField]))

 //same for the button
 }
}

Here is my ViewController :

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let loginView = LoginView(tempSuperView: self.view)
        loginView.setupViews()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

See LoginView for more infor in the control I am talking about.

Using Bootstrap 3, I don't have an issue because the dropdown menu of the navbar uses ul li, so it would be:

<ul>
  <li><a href="#" bla bla bla>Login</a></li>
</ul>

but in Bootstrap 4:

<a class="dropdown-item">
  LoginView Markup Here
</a>

When the bootstrap 4 code renders it creates a nested a tag

<a class="dropdown-item">
  <a LoginView Link Rendered Here</a>
</a>

Obviously, pressing CTRL + U in the browser shows it doesn't like it (in red), yet I still wish to use this control.

Any suggestions?

I am using FBSDKLoginButton in my app, everything working well, only difference I found out that when ever I try to add the button using the code, it adds up Facebook login button with text "Login with facebook" and when ever I try to put the button through the storyboard it shows "Login" only.

I want to to put the button through storyboard, can I change the style to one which I get through code.

Thanx for helping!!!

        let loginView : FBSDKLoginButton = FBSDKLoginButton()
        self.view.addSubview(loginView)
        loginView.center = self.view.center
        loginView.readPermissions = ["public_profile", "email", "user_friends"]
        loginView.addTarget(self, action: "loginFb:", forControlEvents: UIControlEvents.TouchUpInside)

I have not been able to implement the Facebook button on a Scenexxx.m, I write:

-(void)viewdidLoad 
{
FBLoginView *loginView = [[FBLoginView alloc] init]; 
loginView.center = self.view.center; 
[self.view addSubview:loginView]; 
}

But Warning with loginView with this Warning: Property 'view' not found on object of type 'Scenexxx.m'

Please help me.

I'm creating an app. I've done some basic stuff so far, removed the main storyboard and added some components to the main viewcontroller with code and cartography for constraints

basically nothing is clickable, i have UITextFields that can't be focused and buttons that can't be clicked.

why this is happening? thanks

import UIKit
import Cartography

class LoginViewController: BaseViewController {

    var identifierField: UITextField!
    var passwordField: UITextField!

    override func loadUI() {
        view.clipsToBounds = true
        view.backgroundColor = UIColor.colorPrimary()

        let logoText = UILabel()

        let loginView = UIView()

        logoText.attributedText = NSMutableAttributedString.init(string: NSLocalizedString("APP_NAME", comment: ""))
        logoText.font = UIFont.boldSystemFontOfSize(32.0)

        self.view.addSubview(logoText)

        constrain(logoText, self.view) {
            logo, mainView in
            logo.top == mainView.top + 50
            logo.centerX == mainView.centerX
        }

        identifierField = UITextField()
        identifierField.borderStyle = .Line
        identifierField.placeholder = NSLocalizedString("USER_IDENTIFIER_PLACEHOLDER", comment: "")
        identifierField.textColor = UIColor.whiteColor()


        passwordField = UITextField()
        passwordField.borderStyle = .Line
        passwordField.placeholder = NSLocalizedString("PASSWORD_PLACEHOLDER", comment: "")
        passwordField.textColor = UIColor.whiteColor()


        let loginButton = UIButton()
        loginButton.setTitle(NSLocalizedString("LOGIN", comment: ""), forState: .Normal)

        let registrationButton = UIButton()
        registrationButton.setTitle(NSLocalizedString("REGISTER", comment: ""), forState: .Normal)
        registrationButton.addTarget(self, action: #selector(onRegistrationClicked(_:)), forControlEvents: .TouchUpInside)

        loginView.addSubview(identifierField)
        loginView.addSubview(passwordField)
        loginView.addSubview(loginButton)
        loginView.addSubview(registrationButton)

        view.addSubview(loginView)

        constrain(loginView, logoText, self.view) {
            loginView, logo, mainView in

            loginView.top == logo.bottom + 30
            loginView.width == mainView.width - 30
            loginView.centerX == mainView.centerX
        }

        constrain(loginView, identifierField, passwordField, loginButton, registrationButton) {
            loginView, identifierField, passwordField, loginButton, registrationButton in
            identifierField.top == loginView.top + 30
            identifierField.centerX == loginView.centerX
            identifierField.width == loginView.width

            passwordField.top == identifierField.bottom + 20
            passwordField.centerX == loginView.centerX
            passwordField.width == loginView.width

            loginButton.top == passwordField.bottom + 20
            loginButton.centerX == loginView.centerX
            loginButton.width == loginView.width

            registrationButton.top == loginButton.bottom + 20
            registrationButton.centerX == loginView.centerX
            registrationButton.width == loginView.width
        }
    }

    func onRegistrationClicked(sender: UIButton) {
        print("Register clicked")
        navigationController?.pushViewController(RegistrationViewController(), animated: true)
    }
}

I have a ViewController that has a CollectionView of two cells. One of the cells (LoginView) has the login buttons, which I want the ViewController to handle. The error I'm getting is an unexpected nil even though delegate is set to self in WelcomeViewController.

ViewController

    class WelcomeViewController: UIViewController, SomeDelegate ... {

            func createCollectionView(){
                 let loginView = LoginView()
                 loginView.delegate = self

                 //collectionView related stuff here
                 ...
            }
        ...
            override func viewDidLoad() {
                 super.viewDidLoad()
                 createLayer()
                 createCollectionView()
            }
        ...
            func didPressFacebook() {
                print("pressed")
            }
    }

Protocol looks something like this

protocol SomeDelegate {
    func didPressFacebook()
}

and the view is something like this

class LoginView: UICollectionViewCell, ConfigurableCell {

    var reuseId: String {
        get {
            return "loginView"
        }
    }

    var delegate : LoginButtonHandlerDelegate!

    //Create other view related stuff here
    ...

    let facebookButton = SocialButton(buttonType: .facebook)
    let googleButton = SocialButton(buttonType: .google)

    override init(frame: CGRect) {
        super.init(frame: frame)
        facebookButton.addTarget(self, action: #selector(didPressLogin), for: .touchUpInside)

       //Add subviews and other relatedstuff here
        ...
    }

    ...

    @objc func didPressLogin(){
        if (facebookButton.buttonIs == "facebook") {
            delegate.didPressFacebook()
        }
    }
}

I have a subView named loginView and within that a few other elements, namely loginButton and loginUsername

I am trying to programatically add a Facebook login button that has constraints relative to loginButton, loginView and loginUsername

Here is my code

self.loginView.addSubview(facebookLoginButton)

let facebookLoginButtonTopConstraint = NSLayoutConstraint(
      item: facebookLoginButton, 
      attribute: NSLayoutAttribute.Top, 
      relatedBy: NSLayoutRelation.Equal, 
      toItem: loginButton, 
      attribute: NSLayoutAttribute.Bottom, 
      multiplier: 1, 
      constant: 8
)

let facebookLoginButtonLeadingConstraint = NSLayoutConstraint(
      item: facebookLoginButton, 
      attribute: NSLayoutAttribute.Leading, 
      relatedBy: NSLayoutRelation.Equal, 
      toItem: loginView, 
      attribute: NSLayoutAttribute.Leading, 
      multiplier: 1, 
      constant: 8
)

let facebookLoginButtonWidthConstraint = NSLayoutConstraint(
      item: facebookLoginButton, 
      attribute: NSLayoutAttribute.Width, 
      relatedBy: NSLayoutRelation.Equal, 
      toItem: loginUsername, 
      attribute: NSLayoutAttribute.Width, 
      multiplier: 1, 
      constant: 0
)

self.loginView.addConstraints([
      facebookLoginButtonTopConstraint, 
      facebookLoginButtonLeadingConstraint
])
self.facebookLoginButton.addConstraint(facebookLoginButtonWidthConstraint)

This code is going in my viewDidLoad method. The error I'm getting is:

The view hierarchy is not prepared for the constraint: When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.

Any help greatly appreciated, thanks!

I'm trying to customize the PFLogInViewController and make the background a animated gif , something like that : https://medium.com/swift-programming/ios-make-an-awesome-video-background-view-objective-c-swift-318e1d71d0a2 . That's my code :

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *rs = [[NSString alloc]initWithFormat:@"%d", (arc4random()%4)+1] ;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@%@",@"login_bk_" , rs] ofType:@"gif"];
    NSData *gif = [NSData dataWithContentsOfFile:filePath];

    UIWebView *webViewBG = [[UIWebView alloc] initWithFrame:self.logInView.frame];
    [webViewBG loadData:gif MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
    webViewBG.userInteractionEnabled = NO;
    [self.logInView setLogo:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"waho text"]]];
    [self.logInView.logInButton setTitle:@"Entrar" forState:UIControlStateNormal];
    self.logInView.usernameField.placeholder = @"Usuário" ;
    self.logInView.passwordField.placeholder = @"******" ;
    [self.logInView.passwordForgottenButton setTitle:@"Esqueceu a senha?" forState:UIControlStateNormal];
    self.logInView.signUpButton.titleLabel.text = @"Cadastrar-se" ;
    [self.logInView addSubview:webViewBG];

}

Thank you !

I have a simple login form which looks like this.

enter image description here

When the keyboard appears in portrait, it doesn't interfere with the controls. But In landscape it pretty much covers everything.

enter image description here enter image description here

So I decided to add a UIScrollView and when the keyboard appears, push the controls up to be visible.

My first try was using the IB. I added a scrollview first and pinned it to the superview from all 4 sides. Then I added the login controls on top of it and added the same constraints to them as I had before. But when I run it, it's messed up. I'm getting multiple auto layout errors as well.

enter image description here enter image description here

I think the main cause for all these is the error Scroll View has ambiguous scrollable content height.

enter image description here

Since the IB failed me, I set out to add a scrollview programmatically.

import UIKit

class LoginViewController: UIViewController {

    @IBOutlet private var loginView: UIView!

    private var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        registerForKeyboardNotifications()
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        scrollView = UIScrollView(frame: view.bounds)
        scrollView.backgroundColor = UIColor.brownColor()
        scrollView.scrollEnabled = true

        view.insertSubview(scrollView, atIndex: 0)


        // Adding a tap gesture to the scroll view to dismiss the keyboard
        let tapGestureForView = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
        tapGestureForView.cancelsTouchesInView = false
        scrollView.addGestureRecognizer(tapGestureForView)
    }

    // MARK: - Keyboard Handling
    func dismissKeyboard(recognizer: UIGestureRecognizer) {
        view.endEditing(true)
    }

    func registerForKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    }

    // If the loginView is covered by the keyboard, get the height of the view portion that is covered, add 20 points to it and scroll it up.
    func keyboardWasShown(notification: NSNotification) {
        var info = notification.userInfo!
        var keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
        var loginFormFrame: CGRect = view.convertRect(loginView.frame, fromView: nil)
        var coveredFrame: CGRect = CGRectIntersection(loginFormFrame, keyboardFrame)

        scrollView.setContentOffset(CGPointMake(0, coveredFrame.height + 20), animated: true)
    }

    func keyboardWillBeHidden(notification: NSNotification) {
        scrollView.contentOffset = CGPointZero
    }
}

I initialize a scrollview and insert it below the loginView in the viewDidAppear method. As you can see below it gets added successfully. But there's a problem in the landscape. The scrollview doesn't resize itself to fit the landscape screen (I set the scrollview's background color to brown to see if its working correctly). The rest of the code handles the keyboard showing/hiding and pushing the loginView up to the visible area. This code has been tested before and it works but not in this case. Must be because the issue with the scrollview resizing in the landscape orientation.

enter image description here enter image description here

Then I tried setting constraints to the scrollview programmatically to pin it to all sides instead of defining a frame.

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    scrollView = UIScrollView()
    scrollView.backgroundColor = UIColor.brownColor()
    scrollView.scrollEnabled = true

    let leadingSpaceToSuperview = NSLayoutConstraint(item: scrollView, attribute: .Leading, relatedBy: .Equal, toItem: scrollView.superview, attribute: .Leading, multiplier: 1, constant: 0)
    let trailingSpaceToSuperview = NSLayoutConstraint(item: scrollView, attribute: .Trailing, relatedBy: .Equal, toItem: scrollView.superview, attribute: .Trailing, multiplier: 1, constant: 0)
    let topSpaceToSuperview = NSLayoutConstraint(item: scrollView, attribute: .Top, relatedBy: .Equal, toItem: scrollView.superview, attribute: .Top, multiplier: 1, constant: 0)
    let bottomSpaceToSuperview = NSLayoutConstraint(item: scrollView, attribute: .Bottom, relatedBy: .Equal, toItem: scrollView.superview, attribute: .Bottom, multiplier: 1, constant: 0)

    scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
    scrollView.addConstraints([leadingSpaceToSuperview, trailingSpaceToSuperview, topSpaceToSuperview, bottomSpaceToSuperview])

    println("\(scrollView.bounds.width) -\(scrollView.bounds.height)") // returns 0 for both width and height
    view.insertSubview(scrollView, atIndex: 0)


    // Adding a tap gesture to the scroll view to dismiss the keyboard
    let tapGestureForView = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
    tapGestureForView.cancelsTouchesInView = false
    scrollView.addGestureRecognizer(tapGestureForView)
}

But then the scrollview doesn't appear at all!

I'm asking for either of the following solutions.

  • How to create the same layout as I have at first but with a scrollview through IB without the autolayout errors.

or

  • What am I doing wrong when adding the scrollview programmatically?

I'd really appreciate any help. I also uploaded a test Xcode project with this issue to Dropbox.

Thank you.

I use FBLoginView in my app and I want to Fetch UserInfo in another UIViewController.

I've read the document and it said "using multiple FBLoginView instances in different parts of your app"

I've write some code and it works fine. But I'm not sure if I did it right.

So... Here is what I've done:

LoginView

- (void)viewDidLoad {
[super viewDidLoad];
self.LoginView.readPermissions = @[@"public_profile",@"email",@"user_friends",@"user_birthday"];
self.LoginView.delegate = self;
}

- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView{
if (FBSession.activeSession.isOpen) {
    NSLog(@"login");
    [self dismissViewControllerAnimated:YES completion:nil];
}
}

anotherUIViewController

- (void)viewDidLoad {
[super viewDidLoad];
FBLoginView *fb = [[FBLoginView alloc]init];
fb.delegate = self;

}

-(void)viewDidAppear:(BOOL)animated{
if (!FBSession.activeSession.isOpen){
    [self presentViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"LoginView"] animated:YES completion:nil];
}
}

-(void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
self.ProfilePic.profileID = user.objectID;
self.nameLabel.text = user.name;
}

Did anybody face the same issue as I am?