Swift App Without Storyboard


Swiftのドキュメントを読みながらほむほむと言ってても身に付かないのでやっぱり何か作りつつ、動作確認しつつやっていかないとね!
てことでSwiftでストーリーボードを使わずにアプリを作っていってみます・ω・
(Swiftでアプリではなく、言語自体をさわってみたい場合はplaygroundも用意されています・ω・♪)

ストーリーボードを使わないのは言語の動きを確かめるためです(ストーリーボードをいつもあまり使ってないってのもありますが)

AppDelegateを読む

Emptyでプロジェクトを作成したらAppDelegate.swiftが作成されるので内容をざっとみてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        // Override point for customization after application launch.
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        return true
    }

    -----
    -----
}

わおΣ
とりあえずmainはどこいったんだとかいろいろわからない。

main関数

main関数はなくなりましたΣ
けどmain関数を利用するライブラリなどもあるわけで。使おうと思えば使えるみたいです。
- Swiftのプロジェクトでmain.mを使う

に記載されてましたΣ

Objective-Cのコードを使うためのimport

swiftでObjective-Cのコードを使うには明示的にimportしてあげる必要があります。
UIApplicationDelegateUIResponderを利用したいのでAppDelegateではUIKitをimportしてあげます。

1
import UIKit

こうするとUIKitが使えるようになります。

@UIApplicationMain

Objective-Cではmain関数でUIApplicationMainにAppDelegateを渡していましたが、Swiftでは@UIApplicationMainをAppDelegateクラスのすぐ上に記述することで、同様の内容になるようです。
ということで、今まであったmain関数の中の処理の代わりに、@UIApplicationMainをAppDelegateクラスのswiftファイルに記述します。

クラス

クラスの書き方は

1
2
class [クラス名] : [親クラス,デリゲート...] {
}

こんな形になるみたいです。
:のすぐ後ろの継承したいクラス名、続けてプロトコル名を記載していきます。
もちろんクラスは複数継承することはできないので、親クラスは1つしか記載することができません。
複数のクラスを記述した時は

1
 Multiple inheritance from classes 'UIXXXXX' and 'UIXXXXXX'

こんな感じで怒られましたorz

プロパティ宣言

プロパティの宣言はクラスの一番上に記載します。

1
var window: UIWindow?

UIWindow?の最後にある?nilを許容するかどうかです。
初期値はnilなので、宣言時に初期値を代入しない場合、?をつけておかないとエラーになってしまいます。
これとは別に、nilを入れたくない変数の場合は!を記載しておくと、変数にnilを代入しようとするとエラーになるようになっています。
※このエラーが起きるのは実行時です。

関数

1
2
func [関数名]([引数変数]:[引数型], ...) -> [戻り値型]{
}

こんな感じで記載します。

Objective-C

1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Swift

1
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool

Windowの初期化処理

記載する内容は同じですが、ここもSwiftの記述に書き換えます。

Objective-C

1
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

Swift

1
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

Swiftだと初期化時にallocをわざわざ呼び出す必要がなくなりました。
今までのものをSwiftに書き換える場合、初期化を表すinitinitWithは切り取り、その後ろの続く部分の先頭を小文字にして()の一番前の部分に記載します。
initWithFrame: => (frame: )

Objective-C

1
UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

Swift

1
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

ほかのものも同様にこのような形に変換されています。   ちなみに.Grouped.はenumであることを表しています。

1
self.window!.backgroundColor = UIColor.whiteColor()

このself.window!にある!はやはりnilを許容しない意味で、self.window.backgroundColorに値を代入する際、self.windownilであってはいけないため!をつけておきます。

ViewControllerをセットする

今回はよくある形のNavigationControllerに独自のViewControllerを持たせる形にしてみます。

SwiftViewController

1
2
3
4
5
6
7
8
9
10
11
import UIKit

class SwiftViewController: UIViewController {
    init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
        super.init(nibName:nibNameOrNil, bundle:nibBundleOrNil)
        self.view!.backgroundColor = UIColor.redColor()
    }
    override func viewDidLoad(){
        super.viewDidLoad()
    }
}

ViewControllerはいつも通り初期化メソッドとviewDidLoadを作っておきます。 わかりやすいように背景色を赤にしてみました。

AppDelegateで初期化

1
var navigationController: UINavigationController?

navigationControllerをプロパティに持たせて、SwiftViewControllerと一緒に初期化します。

1
2
3
var swiftController: SwiftViewController? = SwiftViewController(nibName: nil, bundle: nil)
self.navigationController = UINavigationController(rootViewController: swiftController)
self.window!.rootViewController = self.navigationController

これで第一段階完成!
無事コントローラーを1つセットして、基本となる形を作り出すことができました。

参考サイト

Comments