カテゴリー: テクノロジー

Extensionで変数(Stored Property)を定義する方法

Apple-Swift1_201603151208394f1.jpg
Swiftの基本のルールですが、Extensionで
・Method (メソッド、即ちファンクション)
・Computed Properties(計算型変数)
は定義できまるのに対して、
・Stored Property(保持型変数)
は定義することができません。

保持型変数と計算型変数の違いを簡単に説明しますと、保持型プロパティとは、データを保持してくれる、とても一般的な変数です。
計算型プロパティとは、すでに定義されている保持型プロパティを操る、getとsetのある、ファンクションに近い変数です。新たなデータを保持することはできません。

つまり、普通の保持型変数をクラスに追加したい場合、Extensionでではなく、クラスの中で定義しなければなりません。

けれども、Appleのライブラリのクラス(UIViewなど)のコードはアクセスできないため、そのようなクラスに新たな変数を定義することはできません。

もちろん、こういうようなクラスにサブクラスを作って、変数をサブクラスで定義できますので、問題はありません。
例えば、UIView の背景色が何回変わったかを記録する変数を付け加えようと思ったら、ColorChangingUIViewというSubclassを作って、そのクラスに変数を入れたら、解決されます。

SubclassでUIViewに変数を加える方法

 
上記の例では、単純に3つのColorChangingUIViewを作りましたので、問題はありませんでしたが、同じように、背景色が何回変わったかを記録する変数を持つUITableViewやUIButtonやUILabelなどを用意しようと思ったら、それぞれ、ColorChangingUITableView、ColorChangingUIButton、ColorChangingUILabelをつくる必要があります。
 
なお、同じ変数名を定義しても、ColorChangingUIViewとColorChangingUITableViewとColorChangingUILabelなどをループで取り扱う際、if is でそれぞれのタイプを確認しないと、colorChangesの変数がアクセスできないため、コードは複雑になり、大混乱になりやすい状態です。
 
それぞれのUIViewのSubclassにSubclassを作る場合のカオス

やっぱり、全てのクラスが親クラスとして共有しているUIViewのコードに変数入れることができたら、解決されますね。
それで、以下は、UIViewに保持型変数を入れる方法となります。

UIViewに保持型変数を入れる場合

わかりやすい上、重複を防げた簡潔なコードになりましたね。
これからも、Swiftの開発、頑張りましょう!


キーボードとともに、UIViewをずらす方法

Apple-Swift1.jpg

SwiftでiOSアプリを開発していますが、キーボードが表示される時のレイアウトで困っている方は少なくないと思います。
キーボードが表示されると、ページの下部が見えなくなったりなどの問題が発生し、エンドユーザに迷惑を掛けないように、キーボードの表示・非表示に反応するアプリを作れたらいいなと思います。

ところで、本日は、iOSのUITextFieldなどのキーボード表示とともに、UIViewをずらす方法を紹介したいと思います!
まずは、とても簡単なSingleViewアプリを用意させていただきました。


 
はるかにシンプルなアプリですが、ページの真ん中あたりに、グレー色なUITextField (文字入力欄)があり、押すとキーボードが開きます。
ページの下にオレンジ色なUIView(長方形)もあり、それをタップすると、キーボードが閉じます。
 
swiftKeyboard1.png
 
けれども、問題!
キーボードが開くと、下のオレンジ色のUIViewが見えなくなり、キーボードを閉じることができません。
 
swiftKeyboard2.png
 
それを修正するには、NSNotificationは使えます!
NSNotificationとは、引き金のようなものとイメージしたらいいと思いますです。
 
キーボードのフレームが変わった時に、オレンジ色のUIViewの位置をずらしたいと思うので、今回の例で引きたい引き金は「UIKeyboardWillChangeFrameNotification」となります。
 
では、この「UIKeyboardWillChangeFrameNotification」が引かれたら、「UIViewを適切にずらす」というコードを書きましょう!
他にも、様々なやり方はあると思いますが、解りやすい例として、以下の方法を紹介したいと思います。
 
1. まず、UIKeyboardWillChangeFrameNotificationが引かれたら、keyboardWillChangeファンクションを呼ぶ
NSNotificationCenter.defaultCenter().addObserver(self, selector: “keyboardWillChange:”, name: UIKeyboardWillChangeFrameNotification, object: nil)
 
2. このファンクションで、キーボードフレームの上部(minY)を取る
var keyboardTop = self.view.frame.height – (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)!.CGRectValue().minY
 
3. その新しい高さをどこかに保存する(今回は別クラスのstatic varに保存する)
KeyboardOverlay.newTop = keyboardTop
 
4. UIViewの位置をキーボードの新しい位置と以前の位置の差異の分で引き足しする。
footer.frame.origin.y = footer.frame.origin.y + (KeyboardOverlay.currentTop – KeyboardOverlay.newTop)
 
5. キーボードの現在の位置を保存する。
KeyboardOverlay.currentTop = keyboardTop
 
合わせたら、コードは以下のようになります。
 

試しましょう〜

 

動いています!
これからも、Swiftの開発、頑張ります!


Swift2でUISearchBarの背景透過

UNIQLOのヒートテックタイツを履いたら怖いものがなくなりました。
マエダです。

Apple-Swift1.jpg

Swift2でiOSアプリを開発してますがUISearchBarの背景透過について紹介します。
# あまり情報なくバッドノウハウだったらすみません。。

Swift1系でも同じことをしたい方は多数いらっしゃったようです。
参考
http://ja.stackoverflow.com/questions/7315/uisearchbar%E3%81%AE%E8%83%8C%E6%99%AF%E3%81%AEview%E3%82%92%E9%80%8F%E6%98%8E%E3%81%AB%E3%81%97%E3%81%9F%E3%81%84

Swift2になるとSubViewアクセスできない風じゃないですか。。。
そこで参考サイトにインスパイアされて以下のようにすると実現できました。

setBackgroundImageで空のUIImageを設定してあげてます。

そもそもなんでUISearchBarの背景色指定させてくれないんだろう。。教えてエロいヒト。


Docker使ってみました

突然寒くなりましたね。
開発担当のノリフミです。

最近サーバーサイドを少し触らせてもらってるのですが
Dockerという素晴らしいのに得体の知れないものを手懐けようと奮闘してる日々です。

自分なりにこうしたらいいのでは?
っと思ったこと残しておこうかと。

そもそも、Dockerって?

docker.png

「Docker」とは、Docker社(旧dotCloud)が開発するオープンソースのコンテナー管理ソフトウェアの1つです。

なんて記述をみつけましたが、分かる人には分かりますが、分からない人はさっぱりですよね。

簡単にいうと、「皆んなが使えて、目に見えないパソコンを簡単に管理(作成・編集・削除等)できるソフトウェア」という感じでしょか(逆にわからない)

前置きはこれくらいにして、ここから本題…

マウントでコンテナ生成してみた

wordpressの公式イメージをpull

docker pull wordpress:latest

コンテナ生成

docker run –name container-name -it
–link container-mysql:mysql
-p 8080:80
-v /home/user/html:/var/www/html
-v /home/user/conf/apache2/sites-available/000-default.conf:/etc/apache2/sites-available/000-default.conf
-v /home/user/conf/php/php.ini:/usr/local/etc/php/php.ini
-e ‘WORDPRESS_DB_HOST=mysql’
-e ‘WORDPRESS_DB_USER=user’
-e ‘WORDPRESS_DB_PASSWORD=password’
-e ‘WORDPRESS_DB_NAME=db_name’
wordpress:latest bash

※ここで問題発生!
カスタマイズすればするほど-vが
増える!
増える!!

そこで考えるノリフミ…
「そうかDockerfileにしてしまえば!」

※ここでまたまた問題発生!!
DockerfileでCOPYしてコンテナ生成しても、起動後のホスト側での編集がコンテナに反映されない…

そこでノリフミは思いました。
「-vとDockerfileってどっちがいいんだ?」

-vとDockerfileどっちが良いのか

要点整理
-vでマウントいっぱい

    • ホストから設定書き換えれる!
    • imageも公式wordpressだけで済むし簡単!
    • 生成コマンド(run)が度々変わる
    • 生成後にもコンテナ内作業がいる場合がある

 

Dockerfileでまとめる

    • COPYなりで設定ファイル追加すると、設定変えたらimage作り直し
    • 環境ごとにimage増える
    • 生成はimageからだから生成コマンドが簡単!
    • 生成後に作業がいらない!

 

色々と記事を探していると、こんなのみつけました。

Dockerが提供するのは、アプリケーションの実行環境を「Dockerイメージ」としてイメージ化する機能、そして、Dockerイメージから実際にアプリケーションを起動する実行環境を提供するという機能です。この「実行環境のイメージ化」こそが、Dockerの中心となる機能です。

なるほど。
imageどんどん作ってけよってことですよね。

それではDockerの考え方に基づいて、構築しよう。

Docker build時の仕様

その前に、Dockerのbuildする時に注意点が何点かあります。

    • COPYとADDの違い
      COPYは純粋にコピーするだけADDはzipなどの解凍もします。
      なのでコピーするだけであればCOPYを使いましょう。

 

    • コンテキスト(読み込めるファイルとか)
      読み込むDockerfileのある階層のファイルorディレクトリか
      設定しているコンテキスト内しかアクセスできません。
      なので、COPYしたいファイル等はDockerfileと同じ階層に設置しましょう。
      逆にコンテキスト内に不要ファイル(重いファイルとか)を設置していると
      勝手に読み込まれるので整理しましょう。

 

Dockerfileでコンテナ生成してみた

上記を踏まえてファイル構成はこんな形に

├── Dockerfile
└── conf
├── apache2
|  └── sites-available
|     └── 000-default.conf
├── docker-entrypoint-initdb.d
└── php
└── php.ini

Dockerfile生成

vi Dockerfile
FROM wordpress
MAINTAINER user
COPY conf/docker-entrypoint-initdb.d /docker-entrypoint-initdb.d/
COPY conf/apache2/sites-available/000-default.conf /etc/apache2/sites-available/
COPY conf/php/php.ini /usr/local/etc/php/
RUN a2ensite 000-default
RUN a2enmod headers
RUN a2enconf security

image生成

docker build image_name ./

コンテナ生成

docker run –name container_name -it
–link container-mysql:mysql
-p 8080:80
-e ‘WORDPRESS_DB_HOST=mysql’
-e ‘WORDPRESS_DB_USER=user’
-e ‘WORDPRESS_DB_PASSWORD=password’
-e ‘WORDPRESS_DB_NAME=db_name’
-v /home/user/html:/var/www/html
image_name:latest bash

無事コンテナ生成終了しましたm(_ _)m

まとめ

Dockerでコンテナ生成するときは最低限のマウントで
後はDockerfileに書いて、どんどんimage作っていこう。
というお話でした。

よくよく考えると当たり前な気もしますが、今でもimageいっぱい作るの抵抗あります…


初めてのiOSアプリ開発 – Santa’s Little Helper

IMG_1830 1
HoHoHo〜 Merry Christmas!

今日はクリスマスイブ!
日本と世界の子供達がサンタからプレゼントもらえる日ですね!

しかも、賢くしていい子でしたらたくさんもらえるといいますよね〜^^

では、今年、皆様はいい子だったのでしょうか?
それを判定できるアプリがありましたらいいよね〜

ということで、作ってみましょう〜

本日はiPhoneやiPadで使えるiOSアプリを作ってみたいと思います〜
とても簡単のもので、初心者でも、Macさえありましたら、作れると思いますよ。
(残念ながら、iOS開発はMacでしかできませんので、Windowsなど、別のOSを利用している方はiOSアプリをつくることはできません。(´□`。)°)

では、早速〜 iOSアプリを作ってみてみたい方は是非お読みください〜

注意
Appleの開発者アカウントをお持ちではない場合、実際の端末でアプリを動かすことはできません。
しかし、Xcodeのシミュレータを使うことによって、実際の端末と同じように動作を見てみることはできますので、iOS開発にお興味がある方は是非、頑張って、作ってみましょう!

Santa’s Little Helper

僕は小さかった時に、「サンタさんはとても忙しいので、お手伝いの妖精がいる」とお母さんに言われました。
英語では「Santa’s Little Helper」といいます。

本日つくるアプリは魔法の力で、もらえるプレゼント数を教えてくれるので、
アプリ名をその「Santa’s Little Helper」にしたいと思います〜

仕様

このアプリは初心者さんでも作れるものので、とても簡単です。

仕様
1.「押してください!」のスクリーンが表示される。
2. スクリーンを押すとサンタさんからもらえるプレゼント数が表示されます。
3. もう一回スクリーンを押すと、最初のページに戻ります。

では、つくりましょう〜!

アプリケーションフォルダーからXcode.appを実行してください。
実行したら、新しいプロジェクトを作成したいので、「Create a New Xcode Project」を押してください。
20151224_2.png

次、かなり簡単な1スクリーンアプリをつくりたいので、「Single View Application」をご選択ください。

20151224_3.png

最後に、以下のように、アプリ名を入れてください。
今回のアプリをAppleストアに出しませんので、Organization Name と Organization Identifier は適当でも問題ありません。
今回のアプリをSwift言語で開発しますので、LanguageをSwiftに切り替えてください。

20151224_4.png

次、アプリのGeneral管理画面が表示されます。この画面より、いろいろ細かいことはできますが、今回は単純にアプリの可能な向きをだけ指定したいと思います。
Portrait = 縦向き
Upside Down = 逆さま縦向き
Landscape Left = 左の横向き
Landscape Right = 右の横向き

それぞれ対応をきちんとできるアプリをつくることも可能ですが、今回は初めてのアプリので、できる限り簡単なものをつくりたいと思います。縦向きのみ対応しましょう〜

20151224_5.png

やった!アプリの開発準備ができました!次はコードを書きましょう!!
左側のメニューをみると、ファイルリストはあると思います。

20151224_6.png

今回、編集するのは ViewController.swift だけです。
それをクリックしたら、以下のようなコードが表示されます。

20151224_7.png

これを説明しましょう〜

説明
import UIKit = Apple社が用意していただいている、UI系のコードを使えるようにする。

class ViewController: UIViewController = このスクリーンはViewControllerです〜ViewControllerは、UIViewControllerの子種類で、ViewControllerはUIViewControllerができることもできます。
ちなみに、UIViewControllerはインポートされたUIKitの一つのもので、スクリーンにものを表示させるのに最適なコードです。

override func viewDidLoad() { = ViewControllerがロードされるとき、この { と数行下にある } の間にあるコードを実行する

super.viewDidLoad() = ViewControllerがロードされるときに初めてやること!superは親である「UIViewController」のことです。つまり、ViewControllerがロードされたら、まずはUIViewControllerがロードされる時に行うことをする。
これはあまり気にしなくて大丈夫です。そのままおいておきましょう!

override func didReceiveMemoryWarning() { = 端末のメモリーがなくなりそうな時、この中のコードを実行する
今回のアプリはメモリー的にものすごい軽いので、今回、これを無視しましょう〜

コード書きましょう!

このアプリに必要なものは以下のとおりです〜

1. 「スクリーンを押してください」という表記()
2. 「サンタからXX個のプレゼントもらえる」という表記
3. そのもらえるプレゼント数

これをコードに書きましょう〜
iOSでラベル的なものを使いた時、UIKitのUILabelというものは最適ですので、1,2に関して、それを使いましょう
プレゼント数は整数となりますので、Int (Integer(和訳:整数)の略)を使います。

このスクリーンにこの3つのものが必要ので、コードに追加しましょう〜

20151224_8.png

説明
var ~~ variableの略。日本語では「変数」。Swift言語では、「この行に書くものは新しい変数ですよ」との意味をします。

var XXX = YYY() ~~ この変数の名前はXXX。XXXの種類はYYY.

つまり、pushPleaseLabelとpresentNumberLabelという UILabel 及び、
presentNumber という Integer (整数) を作りました。

—————–
他にも見えない変数!
—————–

実は、ViewControllerはUIViewControllerの子ので、UIViewControllerからもらっている別の「見えない」変数はたくさん存在しています。

今回のアプリで、背景を表す「view」という、UIView種類の変数も使いたいと思います。
まずは背景色を変えましょう〜

20151224_9.png

説明
self ~~ このViewControllerのインスタンス(つまり、このスクリーン)
self.view ~~ このViewControllerのインスタンスのviewという背景を示すオブジェクト(つまり、このスクリーンの背景)
self.view.backgroundColor ~~ このViewControllerのインスタンスのviewの背景色(つまり、このスクリーンの背景の背景色)

UIColor.redColor ~~ 赤色

Xcodeの左上にある「再生ボタン」を押しますと、シミュレータでアプリの様子を見ることができます。
ロードスクリーン画面が表示される後、赤いスクリーンが表示されたらアプリは正常に動いています。

次、ラベルを用意しましょう!

次、ラベル(「押してください」と「XX個のプレゼントもらえるよ」の表記)をアプリに入れたいですが、
それができるのに、以下のことをしなければなりませんよね。

1.ラベルの位置を定義。
2.ラベルのテキストを定義
3.ラベルのテキストの色を定義
4.ラベルのテキストの配置を定義
5.ラベルのテキストフォントを定義

なお、背景である view に付けたいとおもいますので、それもしなければなりません。

Swiftで、それは、以下のようにできます。
コードは少し長いけど、一行一行読んでみると、非常にわかりやすいと思います。
presentNumber をテキストに入れたいので、”(“と”)”で囲みます

20151224_10.png

また、シミュレータで実行してみると・・・問題!
両方のUILabelが同時に表示されてしまいます!

20151224_11.png

presentNumberLabelの方をを非表示にしましょう。

20151224_12.png

タッチ判定(Touch Detection)

スクリーンをタッチすると、何か起こるようにしたいですね。
Swiftで意外に簡単にできることですよ。

スクリーン(つまり、self.view)にGestureRecognizer(ジェスチャ認識するもの)を追加しましょう〜
スクリーンがタップされるとscreenWasTappedというファンクションを呼ぶようにしましょう。

20151224_13.png

先ほど、片方のラベル (presentNumberLabelの方)を非表示にしましたよね〜
タップすると、ラベルの表示、非表示が変わるように、以下のIF文をscreenWasTappedファンクションに追加しましょう〜

20151224_14.png

シミュレーターで実行してみて、マウスでスクリーンをクリックすると、ラベルが正常に切り替わるはずです!
あとは、presentNumberにランダム数字を与えることと、それをpresentNumberLabelのリフレッシュ(表示させるテキストが変わりますので、再読込が必要です。)

もらえるプレゼント数を決めるのに、本当はクリスマスマジックを使いたいですが、
残念ながら、それはできないので、「Int(arc4random_uniform(XX))」(「XX」は最大数字)というファンクションを代わりに使いましょう〜

20151224_15.png

完成!

とてもとても簡単なアプリですが、第一歩は一番重要と思います!
この記事によって、すこしでもiOS開発を理解できるようになりましたら、本当に嬉しいです〜!

UILabelとIntだけではなくUIViewやUIImageViewなどあり、UIKit以外にも、ゲームに適しているSpriteKitなども存在し、それぞれに色々な特徴があり、たくさん面白いことができますので、頑張ってください!

では、今夜はあまり遅くまで起きないように〜
いい子はちゃんと寝ないとサンタさんからプレゼントもらえませんので〜

Merry Christmas!

20151224_16.png

最終のコード

import UIKit
class ViewController: UIViewController {
var pushPleaseLabel = UILabel()
var presentNumberLabel = UILabel()
var presentNumber = Int()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.redColor()
self.pushPleaseLabel.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height) // x,y,width,height
self.pushPleaseLabel.text = "押してください!"
self.pushPleaseLabel.textColor = UIColor.yellowColor()
self.pushPleaseLabel.textAlignment = NSTextAlignment.Center
self.pushPleaseLabel.font = UIFont(name: "Avenir-Black", size: 14)
self.presentNumberLabel.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height) // x,y,width,height
self.presentNumberLabel.text = "サンタさんから(presentNumber)個のプレゼントもらえます!"
self.presentNumberLabel.textColor = UIColor.whiteColor()
self.presentNumberLabel.textAlignment = NSTextAlignment.Center
self.presentNumberLabel.font = UIFont(name: "Avenir-Black", size: 14)
self.view.addSubview(self.pushPleaseLabel)
self.view.addSubview(self.presentNumberLabel)
self.presentNumberLabel.hidden = true
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "screenWasTapped"))
// Do any additional setup after loading the view, typically from a nib.
}
func screenWasTapped() {
//スクリーンがタッチされると、このコードが実行される
if self.presentNumberLabel.hidden == true { //もし presentNumberLabel が非表示(hidden)になっている場合
self.presentNumberLabel.hidden = false  //presentNumberLabelを表示する
self.pushPleaseLabel.hidden = true      //pushPleaseLabelを隠す
self.presentNumber = Int(arc4random_uniform(5))
self.presentNumberLabel.text = "サンタさんから(presentNumber)個のプレゼントもらえます!"
println(self.presentNumber)
} else {                                    // それ以外の場合(つまり、presentNumberLabelが非表示になっていない)
self.presentNumberLabel.hidden = true   //presentNumberLabelを隠す
self.pushPleaseLabel.hidden = false     //pushPleaseLabelを表示する
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}