Learn Swift / 第18章 ドキュメント・ベースド・アプリケーション
このコーナーでは、Swift による、Mac OS X アプリケーションの作成方法を、説明しています。
ドキュメント・ベースド・アプリケーション
ドキュメント・ベースド・アプリケーションは、複数のドキュメントウィンドウを、開くことのできるアプリケーションです。
ドキュメントウィンドウとは、そのアプリケーションのメインウィンドウのことです。現在では、アプリケーションのウィンドウは、一つにまとめられるようになりました。昔は、メインウィンドウ以外に、メインウィンドウを補助するための、パネルと呼ばれまるウィンドウを、いくつか表示していました。ドキュメントウィンドウという呼び方は、その時の名残です。
Safari や、テキストエディットは、いくつものウィンドウを開くことができます。この仕組みを作るのが、ドキュメント・ベースド・アプリケーションです。
Webs プロジェクト
Xcode を起動して、Cocoa アプリケーションのプロジェクトを作ります。Product Name を、「Webs」にしてください。チェックボックスは、次の図のように、「Use Storyboards」と「Create Document-Based Application」にチェックを入れます。その他のチェックは、すべて外してください。
プロジェクトが開きましたら、実行ボタンをクリックしてください。Webs アプリケーションが起動して、次のようなウィンドウが表示されます。「File」メニューの「New」を選択すると、いくつでもウィンドウが開きます。
コンテンツの作成
今回は、ウィンドウに表示される、コンテンツを、第17章で作成した、「Web ブラウザ」にします。
Main.stroryboard を開いて、「Your document contents here」という、Text Field を削除してください。そして、 第17章 Web ブラウザ を参考にして、Web ブラウザを作り込んでください。
WebKit フレームワークの追加とインポート、App Transport Security の設定も忘れずに!
新規ウィンドウをずらして表示させる
新規ウィンドウを開いても、前のウィンドウと同じ位置に表示されます。これを、ずらして表示させるようにします。
次のリストのように、ViewControler.swift に、新しいプロパティを追加してください。
・・・ class ViewController: NSViewController { var url = "https://www.apple.com/jp/" static var offset = -1 @IBOutlet weak var web: WebView! ・・・static var offset = -1プロパティに static キーワードをつけることによって、そのプロパティは、クラスのプロパティになります。
通常のプロパティは、インスタンスプロパティと呼ばれ、インスタンスが、作成されるたびに、新しいプロパティが作られます。つまり、ウィンドウ一つ一つに、インスタンスプロパティが作られることになります。
一方、クラスプロパティは、クラスに一つしか存在しません。クラスのインスタンス、つまりウィンドウが、いくつ作られても、クラスプロパティは、一つだけです。
次に、viewDidLoad メソッドに、コードを追加します。次のリストの太字部分が追加するコードです。
override func viewDidLoad() { super.viewDidLoad() ViewController.offset += 1 loadWeb() }ViewController.offset += 1先ほど定義した、クラスプロパティ offset を呼び出すには、クラス名.プロパティ名と記述します。ここでは、クラスプロパティ offset の値を一つ増やしています。つまり、ビュー (ウィンドウ) が、作られるたびに、値が、一つ増えることになります。
続けて、ViewWillAppear というメソッドを定義します。
override func viewDidLoad() { super.viewDidLoad() ViewController.offset += 1 loadWeb() } override func viewWillAppear() { var originX = view.window?.frame.origin.x let originY = view.window?.frame.origin.y originX! += CGFloat(ViewController.offset) * 30 view.window?.setFrameOrigin(CGPointMake(originX!, originY!)) }override func viewWillAppear() {viewWillAppar は、ビュー (ウィンドウ) が、表示される直前に、呼び出されるメソッドです。
var originX = view.window?.frame.origin.xview プロパティは、ViewController クラスのスーパークラスである、NSViewController クラスに、定義されているプロパティです。view プロパティは、このビューを表しています。そして、ウィンドウを表す、window プロパティを持っています。そして、そのウィンドウ window の、外枠 frame の、基点 origin の、横方向 x の値を取得しています。横方向の値は、お使いのモニターの左辺から (デスクトップの左辺から)、ウィンドウの左辺までの値になります。取得した値は、変数 originX に設定しています。この値は後ほど変更されますので、変数に、設定しています。なお、window プロパティの後に、? が付いているのは、このプロパティが nil かもしれない可能性を表しています。
let originY = view.window?.frame.origin.y定数 originY に、このビュー view の、ウィンドウ window の、外枠 frame の、基点 origin の、縦方向 y の値を設定しています。縦方向の値は、お使いのモニターの下辺から (デクストップの下辺から)、ウィンドウの下辺までの値です。つまり、ウィンドウの基点 origin は、ウィンドウの左下になります。
originX! += CGFloat(ViewController.offset) * 30変数 originX に、offset の30倍の値を足しています。offset の値は、最初のウィンドウの時に0、2番目のウィンドウの時に1になります。originX はオプショナル型なので、+= で演算する前に、非オプショナル型に戻しています。オプショナル型のままでは、演算することができません。また、offset は、整数型 Int なので、演算する前に、CGFloat 型に変換しています。型の違う、Int 型と CGFloat 型のままでは、演算することができません。
view.window?.setFrameOrigin(CGPointMake(originX!, originY!))setFrameOrigin メソッドは、ウィンドウの基点を設定するメソッドです。CGPointMake は、基点を作成するメソッドです。
コーディングが終わりましたら、Webs アプリケーションを実行してみてください。新規ウィンドウが、前のウィンドウの、30 ポイント右に表示されます。
ウェブサイトのタイトルの取得
次に、WebView に表示されている、ウェブサイトのタイトルを取得して、ウィンドウのタイトルに、設定します。
ViewController の定義に、次のリストのコードを追加してください。
class ViewController: NSViewController, WebFrameLoadDelegate {WebFrameLoadDelegateWebFrameLoadDelegate は、WebView に、ウェブサイトが、読み込まれた時に、実行される、様々なメソッドが、定義されているプロトコルです。プロトコロル (protocol、議定書) については、 第14章 プロトコル で説明しています。
続けて、viewDidLoad メソッドにも、コードを追加します。次のリストの太字部分が、追加するコードです。
override func viewDidLoad() { super.viewDidLoad() web.frameLoadDelegate = self ViewController.offset += 1 loadWeb() }web.frameLoadDelegate = selfWebView の frameLoadDelegate として、self、つまりこの ViewController クラスを設定しています。Delegate (デリゲート、委譲・委任) についても、第14章 プロトコル で、説明しています。
続けて、WebFrameLoadDelegate で定義されているメソッドを、実装します。次のリストのように、メソッドを追加してください。
override func viewWillAppear() { var originX = view.window?.frame.origin.x let originY = view.window?.frame.origin.y originX! += CGFloat(ViewController.offset) * 30 view.window?.setFrameOrigin(CGPointMake(originX!, originY!)) } func webView(sender: WebView!, didReceiveTitle title: String!, forFrame frame: WebFrame!) { sender.window?.title = title }func webView(sender: WebView!, didReceiveTitle title: String!, forFrame frame: WebFrame!)このメソッドは、WebView に表示されているウェブサイトの、タイトルが読み込まれた時に、呼び出されます。
sender.window?.title = titleメソッドによって取得した、ウェブサイトのタイトルを、ウィンドウのタイトルに、設定しています。
ウェブサイトの URLの取得
ウエブサイトの URL を取得して、その取得した URL を、Text Field に表示します。
Text Field と ViewController.swift を、アウトレットで接続します。Name は、「textField」にしてください。
この結果、次のリストのようなコードが、自動的に挿入されます。太字部分が、アウトレットの接続によって、自動的に挿入された、コードです。
・・・ class ViewController: NSViewController, WebFrameLoadDelegate { var url = "https://www.apple.com/jp/" static var offset = -1 @IBOutlet weak var textField: NSTextField! @IBOutlet weak var web: WebView! ・・・続けて、次のリストのとおりに、新しくメソッドを追加します。
・・・ func webView(sender: WebView!, didReceiveTitle title: String!, forFrame frame: WebFrame!) { sender.window?.title = title } func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!) { textField.stringValue = (frame.provisionalDataSource.request.URL?.absoluteString)! } ・・・webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)WebView フレームの、暫定的な読み込みが始まった時に、呼び出されるメソッドです。「フレームの暫定的な読み込みが始まった時」とは、いつのことなのか、私にも分かりません。しかし、Apple Developer に、WebView に表示されたサイトから、情報を入手するには、このメソッドを使うように指定されています。
textField.stringValue = (frame.provisionalDataSource.request.URL?.absoluteString)!Text Field に、読み込んだサイトの、URL を設定しています。
お疲れ様でした。
次章では、昔、Apple から提供されていた、Currency Converter サンプルプログラムを作ります。このチュートリアルは、Objective-C と、nib ファイルによって作られていましたが、それを、Swift と、ストーリーボードに書き換えてみます。
無断転載禁止 Copyright 2016. vivacocoa.jp All right reserved.