iOS_Swift常見錯誤_Thread 1:signal SIGABRT 錯誤解決_學會看Xcode錯誤訊息



Thread 1:signal SIGABRT


介面部分的程式碼架構

AppDelegate.swift

//
//  AppDelegate.swift
//  Test_LoginApp
//
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.makeKeyAndVisible()
        
        window?.rootViewController =
            UINavigationController(rootViewController: ViewController())
        
        
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

ViewController.swift


//
//  ViewController.swift
//  Test_LoginApp
//
//  Created by Abraham on 2017/5/7.
//  Copyright © 2017年 Abraham. All rights reserved.
//

import UIKit

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
    }


    func handleLogout(){
        let loginController = LoginController()
        present(loginController , animated:true , completion:nil)
    }
    
}


LoginController.swift



//
//  LoginController.swift
//  Test_LoginApp
//
//  Created by Abraham on 2017/5/7.
//  Copyright © 2017年 Abraham. All rights reserved.
//

import UIKit

class LoginController: UIViewController {
    //Step7-1.使用swift閉包程式寫法,將step4.中的設定打包出來設置屬性預設值,讓主程式區塊乾淨一點
    let inputsContainerView:UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.white
        view.translatesAutoresizingMaskIntoConstraints = false
        //Step8.修改白子視圖的四個角有圓弧感
        view.layer.cornerRadius = 5
        view.layer.masksToBounds = true
        return view
    }()
    
    //Step9-1. 添加login按鈕元件 , 使用swift閉包寫法
    let loginRegisterButton: UIButton = {
        let button = UIButton(type: .system)
        button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
        button.setTitle("Register" ,  for:.normal)//注意 iOS 10 已經將setTitle(string , forState:) 改為for: 了
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitleColor(UIColor.white, for: .normal)
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
        return button
    }()
    //Step10. 再次使用閉包寫法 生成文本輸入框
    let nameTextField: UITextField = {
        let txtField = UITextField()
        txtField.placeholder = "Name"
        txtField.translatesAutoresizingMaskIntoConstraints = false
        return txtField
    }()
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        //Step1.設置viewController的背景色
        //原先寫法
        //view.backgroundColor = UIColor(red:61/255,green:91/255,blue:151/255,alpha:1)
        //Step3-2.縮短背景顏色設置的程式碼
        view.backgroundColor = UIColor(r:61 , g:91 , b:151)
        
        //Step4.宣告額外蓋在UIViewController上面的View
        //對 顏色 設置為白色
        //對 AutoresizingMask 自動轉化成約束 設置為否
        /*
        let inputsContainerView = UIView()
        inputsContainerView.backgroundColor = UIColor.white
        inputsContainerView.translatesAutoresizingMaskIntoConstraints = false
        */
        
        //Step5.添加上去
        view.addSubview(inputsContainerView)
        //Step9-2
        view.addSubview(loginRegisterButton)
        
        //Step6.設置子視圖的 x,y,寬,高的約束 , 回傳值為 bool
        //need x,y,width,height constraints
        /*
        inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor , constant:-24).isActive = true
        inputsContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        */
        
        //Step7-2-2.替換主程式區塊中為一個function call
        setupInputsContainerView()
        setupLoginRegisterButton()
    }
    
    //Step7-2-1.使用swift 方法 將Step6.中的約束設定 打包出來額外程式區塊
    func setupInputsContainerView(){
        //need x,y,width,height constraints
        inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor , constant:-24).isActive = true
        inputsContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        //need x,y,width,height constraints
        nameTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor , constant:12).isActive = true
        nameTextField.topAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
        nameTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        nameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor , multiplier:1/3).isActive = true
    }
    func setupLoginRegisterButton(){
        //need x,y,width,height constraints
        loginRegisterButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        loginRegisterButton.topAnchor.constraint(equalTo: inputsContainerView.bottomAnchor,constant:12).isActive = true
     loginRegisterButton.widthAnchor.constraint(equalTo:inputsContainerView.widthAnchor).isActive = true
        loginRegisterButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
    }
    
    
    //Step2.
    //覆寫一個『成員變數』(property) , 用來改變上方StatusBar的樣式
    override var preferredStatusBarStyle: UIStatusBarStyle{
        return .lightContent
    }
}
//Step3-1.使用swift 中的 extension擴充型別 對 UIColor這個Class去做參數功能擴充
//RGB自動轉float
extension UIColor{
    convenience init(r: CGFloat , g:CGFloat , b:CGFloat){
        self.init(red: r/255 , green: g/255 , blue: b/255 , alpha: 1)
    }
}

這裡我們可以到下方的 Console 查看錯誤訊息




It says that it's expecting the window to have a root view controller

表示希望窗口視圖可具有根視圖控制器


因此通常會出現這種麻煩錯誤的時候通常是
少加了一句

window?.rootViewController =
            UINavigationController(rootViewController: ViewController())


指定根視圖控制器的型態及初始化 語句

不過目前問題並非如此


我們可以再查看一次錯誤訊息



Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x608000274480 "UITextField:0x7fb466522660.left"> and <NSLayoutXAxisAnchor:0x608000274500 "UIView:0x7fb466407770.left"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'











留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header