Swift特殊extension語法結構_建一個convenience constructor



首先. 建好一個空ios專案  (swift/iPhone)



切至 AppDelegate.swift


撰寫之前有跟大家介紹過的三段
程式碼

有疑惑的可以參考這篇部落格教學
http://coolmandiary.blogspot.tw/2017/04/iosforbegineerios.html


var window: UIWindow?
我們藉由上方預設所產生的 window容器來

Step1.
設定於應用程式載入前的 佈局設定
讓他等於手機屏幕大小(手機邊界)

window = UIWindow(frame: UIScreen.main.bounds)

Step2.
讓這個Window可被顯示看見

window?.makeKeyAndVisible()


Step3.
我們於上一篇教學中是跟大家分享    讓 Window  去讀此 View

window?.rootViewController = ViewController()

這裡是改成於上方 Top處放置一個  導覽列控制器

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


幹嘛這麼傻呢 ???要用程式碼去生成元件??你有沒有想過目的何在??

直接在storyboard拖拉元件
也可以而且較直觀ㄚ
何必要用程式碼生成介面



因為呢.....根據Brian Voong前輩的經驗和他在針對iOS程式開發的操作習慣中
他也分享了自身想法及開發經驗

他覺得

第一.Xcode 開發環境實在有點像一塊批撒捨麼料都放上去
放太滿了,有時候不好找到自己要的東西、而且空間窄
在 Xcode中搜尋元件之後要再Zoom in Zoom out(拉遠近)
調整位置後再放置元件
是很不方便的


第二.直接用程式去替代 預設storyboard介面
改至自己要的形式更加迅速
用程式針對各個元件去做屬性(顏色、圖片、寬、高)做設定
會比還要一個一個去點 然後到右側找各個屬性作調整快


第三.直接用storyboard去做修改再進行compile
預設會針對整個project去做編譯很耗時
會讓開發時間變慢


這裡一執行的效果如下圖所示:
上方處預設生成白色淺灰的 NavigationBar

切至ViewController.swift
來修改預設的   viewcontroller




之後就會看到白色背景的 tableview

使用  滑鼠去滑動就能看見  黑色一條條的 tableview cell lines


緊接著在 ViewController.swift 中
我們想生成一個位於  左上角的 按鈕


這裡預留一個

func handLogout(){

}

函數程式區塊

思考的設計模式為
當我按下左上腳的 Logout 按鈕
我就觸發    launch  一個新的ViewController的功能

這裡養成好習慣

右鍵 --> New Group

創建一個 Folder 取名為 Controller

於此Folder下  右鍵  新增 Cocoatouch class  的 程式 File

生成一個繼承於 UIViewCOntroller的 子視圖介面


刪除一些沒必要程式

一開始我們先更改這個 彈出來的新視圖被景色

這裡讓大家看一下  UIColor這個 Class 當中接受的型態為
CGFloat 這個 struct
import Foundation
import UIKit

//
//  UIColor.h
//  UIKit
//
//  Copyright (c) 2005-2016 Apple Inc. All rights reserved.
//

@available(iOS 2.0, *)
open class UIColor : NSObject, NSSecureCoding, NSCopying {

    
    // Initializers for creating colors
    public init(white: CGFloat, alpha: CGFloat)

    public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)

    public init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

    @available(iOS 10.0, *)
    public init(displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

    public init(cgColor: CGColor)

    public init(patternImage image: UIImage)

    
    @available(iOS 5.0, *)
    public init(ciColor: CIColor)

    
    // Some convenience methods to create colors.  These colors will be as calibrated as possible.
    // These colors are cached.
    
    open class var black: UIColor { get } // 0.0 white

    open class var darkGray: UIColor { get } // 0.333 white

    open class var lightGray: UIColor { get } // 0.667 white

    open class var white: UIColor { get } // 1.0 white

    open class var gray: UIColor { get } // 0.5 white

    open class var red: UIColor { get } // 1.0, 0.0, 0.0 RGB

    open class var green: UIColor { get } // 0.0, 1.0, 0.0 RGB

    open class var blue: UIColor { get } // 0.0, 0.0, 1.0 RGB

    open class var cyan: UIColor { get } // 0.0, 1.0, 1.0 RGB

    open class var yellow: UIColor { get } // 1.0, 1.0, 0.0 RGB

    open class var magenta: UIColor { get } // 1.0, 0.0, 1.0 RGB

    open class var orange: UIColor { get } // 1.0, 0.5, 0.0 RGB

    open class var purple: UIColor { get } // 0.5, 0.0, 0.5 RGB

    open class var brown: UIColor { get } // 0.6, 0.4, 0.2 RGB

    open class var clear: UIColor { get } // 0.0 white, 0.0 alpha

    
    // 0.0 white
    // 0.333 white 
    // 0.667 white 
    // 1.0 white 
    // 0.5 white 
    // 1.0, 0.0, 0.0 RGB 
    // 0.0, 1.0, 0.0 RGB 
    // 0.0, 0.0, 1.0 RGB 
    // 0.0, 1.0, 1.0 RGB 
    // 1.0, 1.0, 0.0 RGB 
    // 1.0, 0.0, 1.0 RGB 
    // 1.0, 0.5, 0.0 RGB 
    // 0.5, 0.0, 0.5 RGB 
    // 0.6, 0.4, 0.2 RGB 
    // 0.0 white, 0.0 alpha 
    
    // Set the color: Sets the fill and stroke colors in the current drawing context. Should be implemented by subclassers.
    open func set()

    
    // Set the fill or stroke colors individually. These should be implemented by subclassers.
    open func setFill()

    open func setStroke()

    
    // Convenience methods for getting components.
    // If the receiver is of a compatible color space, any non-NULL parameters are populated and 'YES' is returned. Otherwise, the parameters are left unchanged and 'NO' is returned.
    @available(iOS 5.0, *)
    open func getWhite(_ white: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

    @available(iOS 5.0, *)
    open func getHue(_ hue: UnsafeMutablePointer<CGFloat>?, saturation: UnsafeMutablePointer<CGFloat>?, brightness: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

    @available(iOS 5.0, *)
    open func getRed(_ red: UnsafeMutablePointer<CGFloat>?, green: UnsafeMutablePointer<CGFloat>?, blue: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

    
    // Returns a color in the same color space as the receiver with the specified alpha component.
    open func withAlphaComponent(_ alpha: CGFloat) -> UIColor

    
    // Access the underlying CGColor or CIColor.
    open var cgColor: CGColor { get }

    
    @available(iOS 5.0, *)
    open var ciColor: CIColor { get }
}

extension UIColor {

    /// Creates an instance initialized with the given properties of a color
    /// literal.
    ///
    /// Do not call this initializer directly. Instead, initialize a variable or
    /// constant using a color literal.
    @nonobjc required public convenience init(colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float)
}

extension CIColor {

    
    @available(iOS 5.0, *)
    public convenience init(color: UIColor)
}


所以為了改背景色首先在 LoginController.swift之中
這裡給予接收參數是以Float來進行給予

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

import UIKit

class LoginController: UIViewController {

    override func viewDidLoad() {
        
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        view.backgroundColor =
            UIColor(red:61/255,green:91/255,blue:151/255,alpha:1)
    }
}

之後為了讓 StatusBar在跳轉同時改為亮白色
我們添加一個覆寫父類別中的成員變數

注意 在過去他是用  func覆寫方法的模式
現在須改為  覆寫一個成員變數


這裡各位可以看看當我們在指定顏色的時候
由於float的關係 , 因此我們連續打了255三次
你可以想像假設之後我們要指定顏色的同時又要很麻煩的再寫三次255放置於分母
是一件十分沒有效率和讓程式碼冗長的事情

有時候我們不想直接於 UIColor 建構子中設定RGB顏色
的時候

這時就可以利用新語法
extension 語法去做參數承接的延伸處裡



extension又被稱之為擴充型別

主要用於擴充class、struct、enum等項目。

只能針對以下類型。

computed property
method
init
subscript
protocol
nested type

這裡我們就是針對  UIColor  這個 Class
去做 init 部分 的擴充

UIColor內部構造

可以將其想像為  於 預設 init
(實體化區塊尾部 再多添加一個將傳入之RGB參數各個轉為float的運算擴充)

參考link: https://hugolu.gitbooks.io/learn-swift/content/Advanced/ProtocolExtension.html


Convenience 關鍵字主要是來自於
初始化函式當中所區分的兩個種類


Designated Initializer: 
類別主要初始化函式。
必須讓屬於類別本身所有的屬性完成初始化,
然後呼叫父類別的初始化函式繼續完成初始化工作。


Convenience Initialize: 
方便使用者設定的初始化函式。
使用convenience關鍵字並將某些參數定為預設值,
然後呼叫同層的 designaed initializer 或 convenience initializer。


參考:https://hugolu.gitbooks.io/learn-swift/content/Advanced/Class.html

我們將會再特別針對 Class去做一個專欄探討

這裡我們可以在此做修改
將原先的
view.backgroundColor =
            UIColor(red:61/255,green:91/255,blue:151/255,alpha:1)


改為簡短的
view.backgroundColor = UIColor(r:61 , g:91 , b:151)

















留言

這個網誌中的熱門文章

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

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

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