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.'
留言
張貼留言