Making the splash view, login, and sign up

Dark Mode

As I said before, I made some logo for our project. But making logo alone is not the end of making logo.

Logo confirmation

So I sent my logo to my team members for confirmation. They were all glad of the logo and agreed to use this logo as our app icon.

Then, we started to develop our project as team. As I am iOS developer in this project, I met with my iOS members and started to develop iOS app.

We started from the very beginning.

Splash view

Splash view code is like this.

//
//  SplashViewController.swift
//  ExplogFB
//
//  Created by 황재욱 on 2017. 11. 28..
//  Copyright © 2017년 becomingmacker. All rights reserved.
//

import UIKit
import SnapKit
import Firebase

final class SplashViewController: UIViewController {
    
    // MARK : 1 - UI Properties
    
    fileprivate let actiIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    fileprivate var splashLogoView: UIImageView!
    fileprivate var splashLogoLabel: UILabel = {
        var splashLabel = UILabel()
        splashLabel.text = "Explog"
        splashLabel.textColor = UIColor(hex: "3b5998")
        splashLabel.font = UIFont.systemFont(ofSize: 30)
        return splashLabel
    }()
    fileprivate var backgroundImgView: UIImageView = {
        var backgroundImg = UIImageView()
        backgroundImg.image = #imageLiteral(resourceName: "background")
        return backgroundImg
    }()
    var blurEffectView : UIVisualEffectView!
    
    // MARK : 2 - Other Properties
    
    var remoteConfig : RemoteConfig!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.remoteControlHandler()
        
        // blur 효과 넣기
        let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.regular)
        self.blurEffectView = UIVisualEffectView(effect: blurEffect)
        self.blurEffectView.frame = self.view.bounds
        self.blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.backgroundImgView.addSubview(blurEffectView)
        
        // indicator setup
        self.view.addSubview(actiIndicator)
        self.backgroundImgView.addSubview(splashLogoLabel)
        actiIndicator.snp.makeConstraints { (actiIndicator) in
            actiIndicator.center.equalToSuperview()
        }
        
        //
        self.view.addSubview(backgroundImgView)
        backgroundImgView.snp.makeConstraints { (backgroundImg) in
            backgroundImg.top.equalToSuperview()
            backgroundImg.bottom.equalToSuperview()
            backgroundImg.leading.equalToSuperview()
            backgroundImg.trailing.equalToSuperview()
        }
        makeSplashLogo()
        setupLogoLabel()
        logoAnimation()
        
    }
    
    // MARK : 3 - RemoteConfig 받아오기
    
    func remoteControlHandler(){
        
        remoteConfig = RemoteConfig.remoteConfig()
        let remoteConfigSetting = RemoteConfigSettings()
        remoteConfig.configSettings = remoteConfigSetting
        remoteConfig.setDefaults(fromPlist: "RemoteConfig")
        remoteConfig.fetch(withExpirationDuration: 0) { (status, err) in
            switch status {
            case .success:
                self.remoteConfig.activateFetched()
                print("fetched")
            case .failure:
                print("fail")
            default:
                print("default")
            }
            self.remoteControlProblemAlert()
        }
    }
    
    // MARK : 4 - RemoteConfig 통한 알림
    
    func remoteControlProblemAlert() {
        var remoteConfingService = remoteConfig["remoteServiceControl"].boolValue
        //remoteConfingService = false
        if remoteConfingService {
            let alertCon = UIAlertController(title: "서버 점검중",
                                             message: "빠른 시일내에 서비스 재개 하겠습니다.",
                                             preferredStyle: .alert)
            alertCon.addAction(UIAlertAction(title: "확인",
                                             style: .default,
                                             handler: { (_) in
                                                exit(0)
            }))
            present(alertCon, animated: true, completion: nil)
        } else {
            
        }
        
    }
    
    // MARK : 5 - splash 로고 만들기
    
    private func makeSplashLogo() {
        splashLogoView = UIImageView()
        self.backgroundImgView.addSubview(splashLogoView)
        splashLogoView.image = UIImage(named: "logo_blue")
        splashLogoView.snp.makeConstraints { (splashlogo) in
            splashlogo.center.equalToSuperview()
            splashlogo.width.equalTo(150)
            splashlogo.height.equalTo(150)
        }
    }
    
    private func setupLogoLabel() {
        splashLogoLabel.snp.makeConstraints { (splashLabel) in
            splashLabel.center.equalToSuperview()
        }
        splashLogoLabel.alpha = 0
        
    }
    
    // MARK : 6 - splash 로고 애니메이션
    
    private func logoAnimation() {
        UIView.animate(withDuration: 2, animations: {
            //self.splashLogoView.alpha = 0
            //self.splashLogoView.transform = CGAffineTransform(scaleX: 0.5, y: -0.5)
            self.splashLogoView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 4))
            //self.splashLogoView.center.x += 100
        }) { (_) in
            UIView.animate(withDuration: 0.5, animations: {
                self.splashLogoLabel.alpha = 1
                self.splashLogoView.alpha = 0
                self.splashLogoView.transform = CGAffineTransform(scaleX: 0.05, y: 0.05)
                //self.splashLogoView.transform = CGAffineTransform(translationX: self.splashLogoLabel.frame.maxY, y: self.splashLogoLabel.frame.maxY)
                
            }, completion: { (_) in
                
                AppDelegate.instance?.presentToLogin()
                
            })
            
            //self.actiIndicator.startAnimating()            
        }
    }
}

It has an animation for the logo.

Login function

Login code is like this.

//
//  LoginViewController.swift
//  ExplogFB
//
//  Created by developer on 2017. 11. 28..
//  Copyright © 2017년 becomingmacker. All rights reserved.
//

import UIKit
import Firebase
import Alamofire

class LoginViewController: UIViewController
{
    // IBOutlets
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var emailTF: CustomTextField!
    @IBOutlet weak var passwordTF: CustomTextField!
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        emailTF.attributedPlaceholder = NSAttributedString(string: "Email Address", attributes: [NSAttributedStringKey.foregroundColor: UIColor(hex: "3b5998")])
        passwordTF.attributedPlaceholder = NSAttributedString(string: "Password", attributes: [NSAttributedStringKey.foregroundColor: UIColor(hex: "3b5998")])
        
        // NotificationCenter for keyboard movement
        NotificationCenter.default.addObserver(self, selector: #selector(keywillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        
        NotificationCenter.default.addObserver(self, selector: #selector(keywillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapAction(_:)))
        self.view.addGestureRecognizer(tapGesture)
    }
    
    // IBActions
    @IBAction func dismissAction(_ sender: Any)
    {
        self.dismiss(animated: true, completion: nil)
    }
    
    @IBAction func loginAction(_ sender: Any)
    {
        guard let email = emailTF.text, let password = passwordTF.text else { return }
        
        let parameters: Parameters = [
            "email" : "\(email)",
            "password" : "\(password)"
        ]
        
        Alamofire.request("http://explog-project-dev.ap-northeast-2.elasticbeanstalk.com/member/login/", method: .post, parameters: parameters, encoding: URLEncoding.httpBody).validate(statusCode: 200..<300).responseJSON { (data) in
            print(data)
        }
    }
}

extension LoginViewController
{
    // selector methods for keyboard movement
    @objc func keywillShow(notification: Notification)
    {
        guard let userinfo = notification.userInfo else { return }
        guard let keyboard = userinfo[UIKeyboardFrameEndUserInfoKey] as? CGRect else { return }
        
        scrollView.setContentOffset(CGPoint(x: 0, y: keyboard.size.height - 200), animated: true)
    }
    
    @objc func keywillHide(notification: Notification)
    {
        scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
    }
}

extension LoginViewController: UITextFieldDelegate
{
    // Actions for pressing return button
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
    {
        if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField
        {
            nextField.becomeFirstResponder()
        } else
        {
            textField.resignFirstResponder()
        }
        
        return false
    }
    
    // Action for keyboard hide when touch
    @objc func tapAction(_ sender: UITapGestureRecognizer)
    {
        self.view.endEditing(true)
    }
}

extension UIColor
{
    convenience init(hex: String)
    {
        let scanner = Scanner(string: hex)
    
        scanner.scanLocation = 1
        
        var rgbValue: UInt64 = 0
        
        scanner.scanHexInt64(&rgbValue)
        
        let r = (rgbValue & 0xff0000) >> 16
        let g = (rgbValue & 0xff00) >> 8
        let b = rgbValue & 0xff
        
        self.init(
            red: CGFloat(r) / 0xff,
            green: CGFloat(g) / 0xff,
            blue: CGFloat(b) / 0xff, alpha: 1
        )
    }
}

And it looks like this.

Sign up function

Sign up code is like this.

import UIKit
import Firebase
import Alamofire

class SignUpViewController: UIViewController{
    
    // MARK: IBOutlet Collection
    @IBOutlet weak var nickNameTextField: CustomTextField!
    @IBOutlet weak var emailTextfield: CustomTextField!
    @IBOutlet weak var passwordTextfield: CustomTextField!
    @IBOutlet weak var confirmPasswordTextfield: CustomTextField!
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var signUpButton: UIButton!
    @IBOutlet weak var profileButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setLayout()
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(noti:)),
                                               name: .UIKeyboardWillShow,
                                               object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(noti:)),
                                               name: .UIKeyboardWillHide,
                                               object: nil)
        // Add Gesture
        let tapGesture = UITapGestureRecognizer(target: self,action: #selector(self.tapAction(_:)))
        self.scrollView.addGestureRecognizer(tapGesture)
    }
    
    // MARK: TapAction
    @objc func tapAction(_ sender:UITapGestureRecognizer) {
        self.view.endEditing(true)
    }
    // MARK: Keyboard Show & Hide
    @objc func keyboardDidShow(noti: Notification) {
        guard let userInfo = noti.userInfo else { return }
        guard let keyFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect else {return}
        scrollView.contentOffset = CGPoint(x: 0, y: keyFrame.size.height - 200)
    }
    
    @objc func keyboardWillHide(noti: Notification) {
        scrollView.contentOffset = CGPoint.zero
    }
    
    // MARK: SignUpButton
    @IBAction func signUpButtonAction(_ sender: UIButton) {
        
        AuthService.signup(email: self.emailTextfield.text!,
                           password: self.passwordTextfield.text!,
                           username: self.nickNameTextField.text!,
                           imgprofile: nil) { (networkData) in
                            print(networkData)
        }
        
//        guard let email = emailTextfield.text, let password = passwordTextfield.text, let username = nickNameTextField.text else { return }
//
//        let imgprofile: Data? = nil
//
//        let parameters : Parameters = [
//            "password1" : "\(password)",
//            "password2" : "\(password)",
//            "email" : "\(email)",
//            "username" : "\(username)",
//            "img_profile" : "\(imgprofile)"
//        ]
//
//        Alamofire.request("http://explog-project-dev.ap-northeast-2.elasticbeanstalk.com/member/signup/", method: .post, parameters: <#T##Parameters?#>, encoding: <#T##ParameterEncoding#>, headers: <#T##HTTPHeaders?#>)
//
//        Alamofire.request("http://explog-project-dev.ap-northeast-2.elasticbeanstalk.com/member/signup/", method: .post, parameters: parameters, encoding: URLEncoding.httpBody).validate(statusCode: 200..<300).responseJSON { (data) in
//            print(data)
//        }
//
//        Alamofire.request(serviceType.routing, method: .post, parameters: parameters).validate(statusCode: 200..<300).responseJSON { (data) in
//            print(data)
//            print(data.result.error)
//            guard let completion = completion else { return }
//            completion(data.result.isSuccess)
//        }
    }
    
    @IBAction func profileButtonAction(_ sender: UIButton) {
        let profileImagePickerController = UIImagePickerController()
        // 2.     UIImagePickerControllerDelegate, UINavigationControllerDelegate 두개 모두 채택!
        profileImagePickerController.delegate = self
        // 3. sourceType설정
        profileImagePickerController.sourceType = .photoLibrary
        // 4. present
        present(profileImagePickerController, animated: true, completion: nil)
    }
    
    // Mark: SetTextField property
    func setLayout() {
        self.passwordTextfield.isSecureTextEntry = true
        self.confirmPasswordTextfield.isSecureTextEntry = true
        self.signUpButton.layer.cornerRadius = 15
        self.signUpButton.layer.borderWidth = 2
        self.signUpButton.layer.borderColor = UIColor.black.cgColor
        
        self.profileButton.layer.borderColor = UIColor(red:0.18, green:0.48, blue:0.96, alpha:1.00).cgColor
        self.profileButton.layer.borderWidth = 1
        self.profileButton.backgroundColor = .clear
    }
    
    
}

// MARK: TextField Delegate
extension SignUpViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        textField.resignFirstResponder()
        
        self.nickNameTextField.tag = 1
        self.emailTextfield.tag = 2
        self.passwordTextfield.tag = 3
        self.confirmPasswordTextfield.tag = 4
        if textField.text?.isEmpty == false {
            switch textField.tag {
            case 1:
                self.emailTextfield.becomeFirstResponder()
            case 2:
                self.passwordTextfield.becomeFirstResponder()
            case 3:
                self.confirmPasswordTextfield.becomeFirstResponder()
            default:
                print("버튼Action을 연결하면 바로 싨행가능.")
            }
        }
        return true
    }
}

// MARK: UIImagePickerDelegate
extension SignUpViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : Any]) {
        if let img = info[UIImagePickerControllerOriginalImage] as? UIImage {
            //detailImageView.image = img
            self.profileButton.setImage(img, for: .normal)
            picker.dismiss(animated: true, completion: nil)
        }
    }
    
    //취소했을때 불리는 델리게이트 메소드
    func imagePickerControllerDidCancel(_ picker:UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
}

Sign up view design is not done, but it looks like this anyway.

댓글

Please enter your comment!
Please enter your name here