2016年12月25日 星期日

Swift3 簡單的鍵盤監控及AlertAction凍結

這邊就不多做解釋了,直接放上Code跟截圖跟大家分享!!


storyboard自行發揮摟~而我為了呈現會擋住textfield所以我故意放比較低

在這要比較注意的是,通常大多數會擋住textfield是因為沒有使用tableview
物件無法滑動的情況下就變成必須改變view的座標,但以下寫法並不適合過多欄位使用。



import UIKit

class ViewController: UIViewController ,UITextFieldDelegate{

    @IBOutlet weak var ShowInputLabel: UILabel!
    @IBOutlet weak var YouerTextField: UITextField!
    @IBOutlet weak var AlertTextLabel: UILabel!
    
    var singleFingerTap:UITapGestureRecognizer!
    var alert:UIAlertController!
   
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.YouerTextField.delegate = self

        //鍵盤監聽
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWasShow), name: .UIKeyboardWillShow, object: nil);
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWasHidden), name: .UIKeyboardWillHide, object: nil);
        singleFingerTap = UITapGestureRecognizer.init(target: self, action: #selector(handleSingleTap));
        
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
        NotificationCenter.default.removeObserver(self)
        // Dispose of any resources that can be recreated.
    }
    
    @IBAction func AlertBtn(_ sender: UIButton) {
         alert = UIAlertController(title: "Alert", message: "輸入下方欄位", preferredStyle: .alert);
        //加入textfieldalert
        alert.addTextField { (text:UITextField) in
            text.placeholder = "輸入"
           //監聽
            NotificationCenter.default.addObserver(self, selector: #selector(ViewController.alertCheck(notification:)), name: .UITextFieldTextDidChange, object: text);
        }
        let alertAction = UIAlertAction(title: "OK", style: .default) { (UIAlertAction) in
            self.AlertTextLabel.text = self.alert.textFields?.first?.text
            //釋放間聽
            NotificationCenter.default.removeObserver(self, name: .UITextFieldTextDidChange, object: nil);
        }
        
        alertAction.isEnabled = false//凍結OK
        alert.addAction(alertAction)
        self.present(alert, animated: true, completion: nil);
    }
    //凍結action(監控)
    func alertCheck(notification:Notification){
        alert = self.presentedViewController as! UIAlertController?
        if(alert != nil){
            let input = (alert.textFields?.first)! as UITextField
            let alertActionOK = alert.actions.last! as UIAlertAction
            //計算字元到多少未解凍
            alertActionOK.isEnabled = (input.text?.characters.count)! > 5
        }
    }
    
    @IBAction func OutPutBtn(_ sender: UIButton) {
        ShowInputLabel.text = YouerTextField.text
    }
//MARK: 鍵盤監聽動作(點view隱藏鍵盤)
    //鍵盤顯示
    func keyboardWasShow(notification:Notification){
        self.view.addGestureRecognizer(singleFingerTap)
        
        //獲取鍵盤高度
        let info = notification.userInfo!
        let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let hieght = keyboardFrame.height
        //改變view座標避免鍵盤擋到textfield(注意:欄位多時不適用)
       self.view.frame.origin.y = -hieght
    }
    //鍵盤收起
    func keyboardWasHidden(notification:Notification){
        self.view.removeGestureRecognizer(singleFingerTap)
        self.view.frame.origin.y = 0
        
    }
    func handleSingleTap(){
        YouerTextField.resignFirstResponder()
    }
    //MARK: 鍵盤按下return後的動作
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        if(textField.text != ""){
            self.OutPutBtn(.init(type:.custom))
        }
        //假設如果有多個欄位要動作時
        /*if(textField.isEqual("第一個欄位")){
            YouerTextField.becomeFirstResponder()//第二個欄位
        }else{
            self.OutPutBtn(.init(type:.custom))
        }*/
        
        return true
    }


}

出來的效果如圖:





2016年12月6日 星期二

swift 多國語系(國際化)

這做法步驟比較多一點,將以圖文解釋。。。
建議先做英文版,畢竟是國際通用語言
再來就是在專案完成後最後在做國際語言,雖然在某些地方會麻煩點。但是storyboard才不用一個一個自己建立ID,主要順續就看個人習慣摟~

選到專案Info下方有個Locallizations,點選下方+選擇你要加入的語言


選擇後會是這樣的(勾起表示要建立多國語系)


建立完成會顯示你所做的語系

再來建立Strings File


命名方式看你個人喜歡摟~


建立完成後會是這樣,這時左邊欄有個Localize...點下去


因為一開始做的語系是預設語系(英文)所以這邊不動他直接建立


建立後將右邊欄位所要增加的語系勾起後如右下圖所示會多出兩個檔案


勾起來後檔案多出外記得去檢查前面所新增的語系跟原本的語系有沒有多一個監控
原本為2 Files Localized要變成3 Files Localized
這樣才能確保code裡面所做的多國語系有用途喔!



下圖是storyboard得多國語系(預設語系為原先就製作好的storyboard)
以下為增加語系要做的動作



接下來要介紹的是如果code內使用多國語系



當然不是做好上方就好拉!!!除了APP名稱其餘都是透過code來詮釋如下:

 override func viewDidLoad() {
        super.viewDidLoad()
       
       //呼叫多國語系
        let labelLanguage = NSLocalizedString("Language", tableName: "InfoPlist", bundle: Bundle.main, value: "" , comment: "");
        //"Language"自訂一個key"InfoPlist"所建立的Strings Flie名稱
        
        //建立label
        let label:UILabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2, y: 200, width: 100, height: 30));
        label.text = labelLanguage//帶入多國語系的值
        self.view.addSubview(label);
    }
呈現出來結果如下:
小提醒:自己建立的key:vaule要注意一定要加入;要不然會有error喔

雖然很簡單,但我就遇過專案怎麼搞都沒有成功過T.T
最後還是建立全新的專案重做才正常。。。
寫的不是很好但希望有幫助參考這篇的你


swift 手勢動作回上一頁

今天要做的是手勢動作回到上一頁,會需要俄未作此動作的原因通常是因為沒有使用NavigayionController的情況下。不然一般如有使用原生就已經幫你做好了

剛好專案因某些設計問題沒有使用到NavigationController,又加上大多數用戶因方便已慣性使用手勢動作(左邊滑向右邊)就可返回上一頁,故花了點時間找資料。
參考連結如下:https://www.hackingwithswift.com/example-code/uikit/how-to-detect-edge-swipes

要怎麼做呢???這是純code的做法
所使用到的是UIPanGestureRecognizer中的方法

首先在viewdidload內執行
let edgePan = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(screenEdgeSwiped))
        edgePan.edges = .left
        

        view.addGestureRecognizer(edgePan)

然後再建立一個func來執行動作
 func screenEdgeSwiped(_ recognizer: UIScreenEdgePanGestureRecognizer) {
        if recognizer.state == .recognized {
            print("Screen edge swiped!")
            let V1 = self.storyboard?.instantiateViewController(withIdentifier: "V1")
            self.present(V1!, animated: true, completion: nil)
        }
    }
這樣就完成了回到上一頁的手勢動作摟~

2016年11月27日 星期日

swift 裝置判別,判別iphone跟ipad 跟手機方向(直向橫向)

當我們有時要開發一個專案兩個種裝置時勢必會需要用到裝置判別,

而最爛最笨的判別方式不外戶就是判別畫面的寬或高,

可是這種笨方法在很多地方容易出現問題。

而官方所提供的原生方法是:

if ( UI_USER_INTERFACE_IDIOM() == UIUsesrInterfaceIdiom.pad ) {
//如果是pad就可會印出來
print("ipad")
}
或是UIUsesrInterfaceIdiom.phone

這樣就能夠判安裝app的裝置是iphone還是ipad了。

並不需要使用型號判別,因為那樣太多型號了。

如果是使用OC的話後面只要將點運算拿掉把P改成大寫即可

至於判斷手機方向只要短短一段即可
 if UIDeviceOrientationIsLandscape(UIDevice.current.orientation){
            print("橫")
        }else{
            print("直")

        }

2016年11月20日 星期日

swift3 AppDelegate 判斷UserDefaults資料後指定頁面

剛好遇到一個算是一次性顯示頁面的功能,又與之前所說的盼斷是否第一次開起有些許差異。

這次是判斷UserDefaults內的某個質如果是空就到起始頁面,如果有資料就跳到另一個頁面。

一開始產生兩種想法:

一是寫在起始頁面的viewdidload判斷,然後在跳轉。缺點是用戶會在瞬間看到起始頁面的畫面,必須用其他方式解決。

二是寫在AppDelegate,判斷有資料就直接跳轉到指定的頁面,好處是不管任何APP第一運行的一定是AppDelegate所以就不會發生第一個想法的問題。

於是最後我選擇了二來做,但發生了沒跳轉的問題。
原本寫法如下:
 if(UserDefaults.standard.string(forKey: "email") != nil){
            let stroyboard = UIStoryboard(name: "Main", bundle: nil);
            let HomeVc = stroyboard.instantiateViewController(withIdentifier: "Home")
            self.window?.rootViewController?.present(HomeVc, animated: true, completion: nil)

        }
並會出現錯誤訊息,大致上是說明層級不同會找不到此頁面之類的

所以上網找了幾個方法後改成這樣:
if(UserDefaults.standard.string(forKey: "email") != nil){
            let stroyboard = UIStoryboard(name: "Main", bundle: nil);
            let HomeVc = stroyboard.instantiateViewController(withIdentifier: "Home")
            let appDelegate = UIApplication.shared.delegate as! AppDelegate;
            appDelegate.window?.rootViewController = HomeVc

        }

經過測試後改寫的方法就是我想要的,希望有遇到相同問題的人有得到幫助喔!

如果你只是要盼斷是否第一次開起的話請參考:

2016年11月14日 星期一

swift3 擷取特定字串 (更:Swift4)

Swift4
原本swfit3的方法雖然笨,但至少有得到所想要的效果。但是在swift4那方法會出現警告,沒意外是即將停用。所以就改寫成以下方法

let Bitrh = "2017-09-21 09:17:07 +0000"
        let year = Bitrh.prefix(4)//取得字串到第幾字元 Bitrh.prefix(Int)
        print("這是年:\(year)")
        
        let Monthstart = Bitrh.index(Bitrh.startIndex, offsetBy: 5)//從第幾字元開始算起
        let Monthend = Bitrh.index(Monthstart, offsetBy: 2)//在Monthstart中從頭取自第幾字元
        let month = Bitrh[Monthstart..<Monthend]//利用rang的方式取出該字元Monthstart是起始至Monthend,因Monthend只要求兩個字元所以month就會印出兩字元
        print("這是月:\(month)")

        let Daystart = Bitrh.index(Bitrh.startIndex, offsetBy: 8)//同月份做法
        let Dayend = Bitrh.index(Daystart, offsetBy: 2)
        let Day = Bitrh[Daystart..<Dayend]

        print("這是日:\(Day)")
打印出來結果就跟swift3是一樣的效果


Swift3
因為某些原因用到了擷取字串,下面所有"111"是用來計算字元用的所以隨便輸入皆可


let date = "2016-11-15"
        
        let dateString = String(describing: date)
        
        print(dateString)
        取出前四個字元使用.substring(to:String.Index)
        let year = dateString.substring(to: "1111".endIndex)
        
        print("年:\(year)")
        從第幾字元開始取用使用.substring(form:String.Index)
        let birthmonth = dateString.substring(from: "11111".endIndex);
        因為只要月份兩字元所以在做一次第一步驟
        let month = birthmonth.substring(to: "11".endIndex)
        
        print("月:\(month)")
        再來第二步驟已經從月開始所以直接在呼叫第二步驟宣告的值在做一次第二步驟
        let birthday = birthmonth.substring(from: "111".endIndex)
        最後再重複一次第一步驟
        let day = birthday.substring(to: "11".endIndex);
        

        print("日:\(day)")

這樣print出來會是這樣,如下圖:

Constraints 直向與橫向(xcode8)

這篇主要以圖片做解析,只坐直向與橫向檢視,不做基本的constraints解說
下圖為直向的constraints


做好後將所有constraints選取起來




 接下來如下圖,在右邊欄最下方有個Installed 的左邊有個+號點下去,如下圖
並按下Add Variation加入一個新的群組



加入後將原本的Installed勾掉





勾掉後轉成橫向左邊所有的Constraints會變半透明,表示它存在,但在此畫面無作用



然後在照做一次直向的動作(注意Constraints是全新的要重做)


然後因為5.5寸跟4.7寸已下在橫向大小在官方設定有些不同所以要做兩次不同的群組
4.7以下我們選的是wChC 但5.5要選的是wRhC
如果沒做wRhC的話在5.5寸是會跑版的


完成後全選所有的 Constraints 會呈現這樣


選任一直向Constraints檢查群組

選任意橫向檢查群組


這樣就完成了直向與橫向不同的Constraints了
希望能夠幫助到大家喔!!!


swift 指定某個子頁能夠作翻轉

因為部分功能需求關系,原本APP預設只限制直向

但在特定指定頁面時怎麼辦呢???
程式碼如下:
在APPDelegate裡面加入

var shouldRotate:Bool = false

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if shouldRotate{
            return .all
        }else{
            return .portrait
        }
    }
由於上方的func屬於強制轉向,所以我使用了.all而非.landscape

然後在你要翻轉的viewcontroller中加入
let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.shouldRotate = true

這樣就能夠在指定的頁面翻轉了,但注意如果storyborad有做constraints
請記得做好直向跟橫向的constraints。要不然畫面轉了也不會有動作喔!

2016年10月5日 星期三

CollectionViewController的應用

先在sotryboard內建立一個collectionviewcontroller
然後再建立一個繼承於UICollectionViewController的class
而此class會幫你建立好cell,但我個人將它移除後自己寫過,也可用系統建立的。
其餘不多說拉!以下看code


import UIKit


class MenuViewController: UICollectionViewController,UICollectionViewDelegateFlowLayout {

    
    override func viewDidLoad() {
        super.viewDidLoad()

      
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
       
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
       
        return 20
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MenuViewCell;
        
        cell.layer.cornerRadius = 10//cell圓角
        cell.nameLabel.text = "這是第\(indexPath.row)cell"
        // Configure the cell
    
        return cell
    }
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        let row = indexPath.row
        print(row)
        
    }

//MARK: CELL內容

    //計算cell上下高
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
        let size:CGSize = CGSize(width: self.view.frame.size.width/2-12, height: (self.view.frame.size.width/2-12)/1.5);

        return size
    }
    //計算cell上下高
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat{
        return 10
    }
    //計算cell左右寬度
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
    {
        return 5
    }
    //cell上下左右留邊
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
        return UIEdgeInsetsMake(10, 6, 10, 6);
    }

    

呈現出來的效果如下

2016年10月3日 星期一

註冊頁面(SWIFT3)

這邊要製作的是註冊頁面,如需登入的朋友們請到http://h81061678.blogspot.com/2016/10/swift3.html
在這跟註冊一樣使用了email格式盼斷,textfield的判斷(return動作)及監聽動作

不多說了一樣先放上code給大家參考

import UIKit

class RegisteredViewController: UIViewController,UITextFieldDelegate {
    
    @IBOutlet weak var TopView: UIView!
    @IBOutlet weak var registeredBtn: UIButton!
    @IBOutlet weak var AgreeBtn: UIButton!
    @IBOutlet weak var eMailField: UITextField!
    @IBOutlet weak var PasswordField: UITextField!
    @IBOutlet weak var PasswordCKField: UITextField!
    @IBOutlet weak var NicknameField: UITextField!
    @IBOutlet weak var BirthyearField: UITextField!
    @IBOutlet weak var BirthmonthField: UITextField!
    @IBOutlet weak var BirthdayField: UITextField!
    
    var UserDef:UserDefaults!
    var agreeCK:Bool!
    var singleFingerTap:UITapGestureRecognizer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //監聽鍵盤動作
        NotificationCenter.default.addObserver(self, selector: #selector(LoginViewController.keyboardWasShown), name: NSNotification.Name.UIKeyboardWillShow, object: nil);
        NotificationCenter.default.addObserver(self, selector: #selector(LoginViewController.keyboardWasHidden), name: NSNotification.Name.UIKeyboardWillHide, object: nil);
        singleFingerTap = UITapGestureRecognizer.init(target: self, action: #selector(handleSingleTap));
        
        agreeCK = false;
        UserDef = UserDefaults.standard
        UserDef.set(agreeCK, forKey: "ck");
        
        AgreeBtn.layer.borderWidth = 1.5;
        AgreeBtn.layer.borderColor = UIColor(red: 77/255, green: 77/255, blue: 77/255, alpha: 1).cgColor
        registeredBtn.layer.cornerRadius = 5;
        
        self.eMailField.delegate = self;
        self.PasswordField.delegate = self;
        self.PasswordCKField.delegate = self;
        self.NicknameField.delegate = self;
        eMailField.clearButtonMode = .always;
        PasswordField.clearButtonMode = .always;
        PasswordCKField.clearButtonMode = .always;
        NicknameField.clearButtonMode = .always;
       
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.isNavigationBarHidden = false
    }
    
    @IBAction func AgrddBtn(_ sender: UIButton) {
        if (UserDef.bool(forKey: "ck") == false){
            agreeCK = true;
            UserDef.set(agreeCK, forKey: "ck");
            print(UserDef.bool(forKey: "ck"))
            AgreeBtn.setBackgroundImage(UIImage(named:"tick"), for: .normal)
        }else{
            agreeCK = false;
            UserDef.set(agreeCK, forKey: "ck");
            print(UserDef.bool(forKey: "ck"))
            AgreeBtn.setBackgroundImage(UIImage(named:""), for: .normal)
            AgreeBtn.backgroundColor = UIColor.white;
        }
    }
    
    
    @IBAction func RegisteredBtn(_ sender: UIButton) {
        if(UserDef.bool(forKey: "ck")==true){
            if(eMailField.text != "" && PasswordField.text != "" && NicknameField.text != "" && BirthyearField.text != "" && BirthmonthField.text != "" && BirthdayField.text != "" && PasswordCKField.text != ""){
                if (self.isValidEmail(testStr: eMailField.text!) == false){
                    print("信箱格式錯誤");
                    let alertcontroller = UIAlertController(title: "Error", message: "The mailbox is malformed", preferredStyle: .alert);
                    let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil);
                    alertcontroller.addAction(alertAction)
                    self.present(alertcontroller, animated: true, completion: nil)
                }else{
                    if(PasswordCKField.text == PasswordField.text){
//                        print(PasswordField.text?.characters.count)
                        if((PasswordField.text?.characters.count)! < 6 || (PasswordField.text?.characters.count)! > 12){
                            let alertcontroller = UIAlertController(title: "Error", message: "The character should be between 6 and 12", preferredStyle: .alert);
                            let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil);
                            alertcontroller.addAction(alertAction)
                            self.present(alertcontroller, animated: true, completion: nil)
                            print("密碼未介於6~12之間")
                        }else{
                            //註冊成功
                            print("註冊")
                        }
                       
                    }else{
                        let alertcontroller = UIAlertController(title: "Error", message: "The passwords do not match", preferredStyle: .alert);
                        let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil);
                        alertcontroller.addAction(alertAction)
                        self.present(alertcontroller, animated: true, completion: nil)
                    }
                    
                }
            }else{
                if(eMailField.text == ""){
                    eMailField.attributedPlaceholder = NSAttributedString(string: "Please enter email", attributes: [NSForegroundColorAttributeName: UIColor.red]);
                }
                if(PasswordField.text == ""){
                    PasswordField.attributedPlaceholder = NSAttributedString(string: "Please enter password", attributes: [NSForegroundColorAttributeName: UIColor.red]);
                }
                if(PasswordCKField.text == ""){
                    PasswordCKField.attributedPlaceholder = NSAttributedString(string: "Please enter password confirm", attributes: [NSForegroundColorAttributeName: UIColor.red]);
                }
                if(NicknameField.text == ""){
                    NicknameField.attributedPlaceholder = NSAttributedString(string: "Please enter nickname", attributes: [NSForegroundColorAttributeName: UIColor.red]);
                }
                if(BirthyearField.text == "" || BirthmonthField.text == "" || BirthdayField.text == ""){
                    let alertcontroller = UIAlertController(title: "Error", message: "Please enter your borthday", preferredStyle: .alert);
                    let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil);
                    alertcontroller.addAction(alertAction)
                    self.present(alertcontroller, animated: true, completion: nil)
                }
                
            }
        }else{
            let alertcontroller = UIAlertController(title: "Error", message: "Please agree membership terms", preferredStyle: .alert);
            let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil);
            alertcontroller.addAction(alertAction)
            self.present(alertcontroller, animated: true, completion: nil)
        }
    }
    // MARK: e-Mail檢查
    func isValidEmail(testStr:String) -> Bool {
        // print("validate calendar: \(testStr)")
        let stricterFilter:Bool = false;
        
        let stricterFilterString:String = "[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}"
        let laxString:String = ".+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*"
        let emailRegex:String = stricterFilter ? stricterFilterString : laxString;
        let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: testStr)
    }
    
    
    // MARK: TEXTField按下鍵盤return後動作
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        if(textField.isEqual(eMailField)){
            PasswordField.becomeFirstResponder()
        }else if(textField.isEqual(PasswordField)){
            PasswordCKField.becomeFirstResponder()
        }else if(textField.isEqual(PasswordCKField)){
            NicknameField.becomeFirstResponder()
        }else if(textField.isEqual(NicknameField)){
            NicknameField.resignFirstResponder()
        }
        return true;
    }
    //MARK: 鍵盤監聽動作(當用戶點view收起)
    func keyboardWasShown(){
        TopView.addGestureRecognizer(singleFingerTap);
    }
    func keyboardWasHidden(){
        TopView.removeGestureRecognizer(singleFingerTap);
    }
    func handleSingleTap(){
        //Do stuff here...
        eMailField.resignFirstResponder()
        PasswordField.resignFirstResponder()
        PasswordCKField.resignFirstResponder()
        NicknameField.resignFirstResponder()

    }

以下附上大概的介面圖剩下就交由大家自己去測試摟!!!