特定のタップイベントを無視する

ビューの中に配置してあるあるボタンだけタップイベントを拾いたいことがあります。
単にuserInteractionEnabled = falseにしてしまうと中に配置してあるボタンも
イベントが無視されるので、hitTestで実装しました。

return nilを返したものだけ、タップイベントが無視されます。

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        if hitView == self || hitView == loadView {
            return nil
        }
        return hitView
    }

Swift勉強8 Stringの主な機能

空チェック

isEmptyを使います。
例)

let result = "Hello".isEmpty

開始文字のチェック

hasPrefixを使います。
例)

let result = "Hello".hasPrefix("He")

終了文字のチェック

hasSuffixを使います。
例)

let result = "Hello".hasSuffix("llo")

整数への変換

toInt()を使います。
例)

let num = "10".toInt()

Swift勉強7 値のキャスト

SwiftはObjective-Cと違い、暗黙的型変換は行われません。
ややこしいのですが、リテラルで変数の値を指定したときは型推論で型が決定しましたが、
別々の型同士の計算などの場合は、暗黙の型変換は行われません。

よって、以下の場合はコンパイルエラーになります。
例)

var i8 : Int8 = 1 // -128〜127 を表現可能
var i16 : Int16 = 1 // -32768〜32767 を表現可能

i8 = i16 // コンパイルエラー : Int16 is not convertible to Int8
i16 = i8 // コンパイルエラー : Int8 is not convertible to Int16

キャストの方法

指定した型に変換する

asUnsigned、asSigned

例)

var i : Int = -1
var ui : UInt = i.asUnsigned() // → 18446744073709551615

var ui8 : UInt8 = 10
var i8 : Int8 = ui8.asSigned() // → 10

指定した型の変数を作る

型(値や変数など)

例)

var i8 : Int8 = 1
var i16 : Int16 = 1

i8 = Int8(i16)  // 型(値や変数など)

numericCast関数

Swiftでは、キャスト用の関数「numericCast」が用意されています。
ただし、左辺の変数では表現できない値の場合は、やはり実行時にエラーになりますので、
値のチェックを行った上で使うことになります。

var i16 : Int16 = 0
var ui32 : UInt32 = 100

i16 = numericCast( ui32 ) // キャストして代入

ui32 = UInt32.max // Int16 では表現できない値
i16 = numericCast( ui32 ) // コンパイルはOK , 実行時にエラー

オーバーフローとアンダーフローの無視

Swiftには「&」を付けることによって、演算結果がオーバーフローやアンダーフローが発生しても、
例外を発生させず無視することができます。いきなりプログラムを終了されることは免れますが、
この方法は問題が解決されたわけではなく、間違った演算結果のままプログラムが進むため、
あまりよいとは言えません。紹介だけしておきます。
例)

num1 = num1 &+ num2 // num1 + num2がIntの最大値を超えても例外を出さない

ゼロ除算問題を無視

ゼロでの除算は例外が発生しますが、これも無視することができます。
ただし、前述したように、これもプログラムを終了されることは免れますが、
この方法は問題が解決されたわけではなく、間違った演算結果のままプログラムが進むため、
あまりよいとは言えません。紹介だけしておきます。同じく「&」を使います。

例)

num1 = num1 &/ num2 // num2が0でも例外を無視

<参考サイト>
http://matome.naver.jp/odai/2140585952879793501

Swift勉強6 Tuple(タプル)

Tupleは型の異なる値を1つのデータのかたまりとして扱うことができます。

Tupleで代入

Tupleは以下のように()の中に複数の種類の値を指定します。
例)

var tpl = (1, "Neko", true)

Tupleの取り出し

Tupleの値を取り出すときは、変数名.インデックスで指定します。
例)

var tpl = (1, "Neko", true)
println(tpl.1)

ラベル付きTuple

Tupleは値が増えると管理が大変になりますが、ラベルを付けることができるため、わかりやすくて便利に扱えます。
例)

var tpl:(num:Int, name:String, age:Int) = (num:1, name:"Neko", age:18)
println(tpl)

// 代入はラベルで指定
tpl.num = 2
tpl.name = "Hoge"
tpl.age = 20
println(tpl)

Tupleはネストできる

例)

var item = ( 1 , "Neko" , ( "Animal" , "Cute" ) )

配列や辞書にも格納できる

例)配列

var items = [ ( "Pen" , 100 ) , ( "Note" , 200 ) ]

例)辞書

var items = [ ( "Pen" , 100 ) , ( "Note" , 200 ) ]

配列と何が違うの?

Tupleは複数の値が入れられますが、それでは配列と何が違うのでしょうか。
配列との違いは以下です。

  • 配列は同じ型しか扱えないが、Tupleは複数の型を扱える(種類を問わない)
  • 配列と違って、Tupleは繰り返し処理で利用できない。(例:for-inなど)

中身はTupleだった!

以下のようにnumはInt型の変数ですが、これも値が1つだけのTupleです。

var num:Int = 100
println(num.0)

さらにTupleについて調べてみました。

<参考サイト>
http://matome.naver.jp/odai/2140583126058968001

上記サイトによると

Swiftの便利な機能の1つである「 タプル ( Tuple ) 」について見ていきましょう。
タプルというのは「 ( "Apple" , 100 ) 」のように、括弧で囲った中に、
型に関係なく値を並べて、これらを1つのデータの塊としてやりとりする仕組みです。

C言語ならば、同様なことを構造体を以下のような定義を行うことで
使うことで実現できますが、タプルは、特に事前の定義もなく使うことが
できるという手軽さがあります。名前の無い構造体のようなイメージです。

// C言語では事前の構造体定義が必要
typedef struct {
char[ 32 ] name;
int price;
} item;

Tupleは名前のない構造体!なるほど。

http://matome.naver.jp/odai/2140634490000675201
上記のサイトにも以下のように書かれています。

Swiftの Int を見ていくと、実は struct で宣言されていることが分かります。
エンディアン指定や、最大最小値もここで宣言されています。

 struct Int : SignedInteger {

   // イニシャライザ
   init()
   init( _ value : Int )
   init( bigEndian value : Int )
   init( littleEndian value : Int )

   static func convertFromIntegerLiteral( value : Int ) -> Int
   typealias ArrayBoundType = Int
   func getArrayBoundValue() -> Int

   // エンディアン指定の取り出し
   var bigEndian : Int { get }
   var littleEndian : Int { get }
   var byteSwapped : Int { get }

   // 最大最小値
   static var max : Int { get }
   static var min : Int { get }

  }

Int には extension がいくつも定義されていて、他の整数型や実数型から
Int を生成するイニシャライザや UInt への変換関数が用意されています。
逆に、ここで定義されていない型から生成することはできず、必要ならば拡張する必要があります。

  extension Int {

   // イニシャライザ
   init( _ v : UInt8 )
   init( _ v : Int8 )
   init( _ v : UInt16 )
   init( _ v : Int16 )
   init( _ v : UInt32 )
   init( _ v : Int32 )
   init( _ v : UInt64 )
   init( _ v : Int64 )
   init( _ v : UInt )

   // UInt への変換
   func asUnsigned() -> UInt

  }

  extension Int {
   init( _ v : Float )
   init( _ v : Double )
   init( _ v : Float80 )
  }

Swift勉強5 nilとOptionalについて

基本的にnilは許可されていない

Swiftでは変数作成時にはnilは許可されていないため、以下のようなコードはエラーとなります。
例)

var name:String = nil   // エラーになる

nilが許可されていないと、変数がnilだったらxxxするなどの処理も不要になります。

Optional型でnilを許可できる

Swiftで基本nilが許可されていませんが、nilを代入することが必要なケースもあります。
そのようなケースには「Optional」という機能をつかうことで、nilを許可できます。
型の後に「?」を付けて、Optional型という値にラップします。

例)

var name:String? = nil  // エラーにならない

Optional型からのアンラップ

一旦Optional型でラップした変数を別の変数へ代入したいケースがあるかと思います。
そのままだと代入できないため、Optional型でラップした変数をアンラップしてから代入します。
Optional型でラップした変数の後ろに「!」を付けることでアンラップできます。

例)

var a:String? = "Neko"
var b:String = a!

Optional型ってなに?

nilを含めて扱うことのできる値の方で、値をラップするための専用の型です。
「?」を付けることで、Optional型にラップ処理を実行できますが、nilが許可されるのは
型がOptional型になるからです。

Swift勉強4 演算子

四則演算子

値の演算の基本である「+」「-」「*」「/」と割り算の余りをもとめる「%」。
また、()を使うと優先順位を指定できます。

またテキストの場合は、「+」演算子で文字を連結することができます。
例)

"Hello," + "Neko!"  // Hello,Nekoになります

代入演算子

値の代入は、「=」で行いますが、四則演算子と一緒になったものを使うと便利です。

代入演算子 説明
A += B AをBに加算してAに代入
A -= B AをBで減算してAに代入
A *= B AとBを乗算してAに代入
A /= B AをBで除算してAに代入
A %= B AをBで割ったあまりをAに代入

例)

var num:Int = 100
num += 200      // numは300になる

インクリメントとデクリメント

インクリメント

例)

a++
++a

デクリメント

例)

b--
--b

なお、以下のようにインクリメント、デクリメントする位置(前or後ろ)によって、num1、num2に代入される値が異なります。

var x:Int = 10
var num1 = ++x  // num1は11

var y:Int = 10
var num2 = y++  // num2は10

比較演算子

比較するための演算子で、制御構文に使用されます。

比較演算子 説明
A == B AとBは等しい
A != B AとBは等しくない
A > B AはBより大きい
A < B AはBより小さい
A >= B AはB以上
A <= B AはB以下
A === B AとBは同じオブジェクト(※参照するものが同じ)
A !== B AとBは同じオブジェクトではない(*参照するものが別)

上記の最後の2つ以外は、数値、テキスト、真偽値など、どんな値でも利用できます。
また、大小などの比較は数値はもちろんですが、テキストでも利用可能です。
例)

var a:String = "A"
var b:String = "B"

var result:Bool = a < b //trueになる

論理演算子

2つの真偽値によって結果を返すのが論理演算子で、制御構文などで使われます。

論理演算子 説明
A && B 論理積(AND)
A || B 論理和(OR)
A ^ B 排他的論理和(XOR)
!A 論理否定(NOT)

三項演算子

真偽値の条件の結果によって、異なる値を返すものです。

// 条件 ? 値1 : 値2 のように記述します
var num = 1
var result = num >= 0 ? "正の数" : "負の数"    // 正の数になります

nil演算子

値がnilかどうかで異なる値を返すのがnil演算子です。
ある変数の値がnilだった場合の対応を記述するケースなどに便利かと思います。
例)

var value = name ?? "none"

Range演算子

整数値の「範囲」を示すための演算子です。

Closed Range演算子

最小値と最大値を指定して範囲を指定します。
例)

1...10  // 1から10まで

Half-Open Range演算子

最小値と最大値(最大値未満の値)を指定して範囲を指定します。
例)

1..<10   // 1から9まで

Closed Range演算子と比べて、Half-Open Range演算子は最大値に指定した値を含みません。
なお、Objective-CのNSRangeのtoRnageを呼び出すことで、SwiftのRnageの値として取り出すことができます。

Swift勉強3 定数と変数

値を入れるものとして定数と変数があります。
定数や変数名は半角英数字や全角文字も使えますが、最初の一文字目は半角数字は使用できません。

定数と変数の記述方法は以下の通りです。

定数の宣言

Objective-Cではconstを使いましたが、Swiftでは「let」を使います。

let num = 123       // 構文「let 変数 = 値」
let num:Int = 456   // 構文「let 変数:型 = 値」
let num:Int     //これはエラーになる

変数の宣言

var num1 = 123      // 構文「var 変数 = 値」
var num2:Int = 456  // 構文「var 変数:型 = 値」
var num3:Int        // これはエラーにならない

num3 = 789

複数の値を変数に代入する

Tupleを利用して代入します。(Tupleは後述します)

var (num1, num2) = (123, 456) // num1に123、num2に456が入る

Swift勉強2 型

Swiftは静的型付けの言語です。
変数や定数は作成時に型が決まるため、指定された型の値しか代入できませんし、その後型を変更することもできません。

型推論

Swiftには「型推論」という機能があります。
ますは、これまで述べてきた変数の宣言を見てみましょう。

var num = 123
let name = "Neko"

上記の変数、定数の宣言をみると、型を指定していません。なぜこのような書き方が可能かというと、Swiftに「型推論」の機能があるからです。
Swiftの「型推論」は、型の指定がされていな場合、代入される値から型を推定して、その型の変数として作成します。

そのため、以下のように型を推測する値がない場合はエラーになります。

var num     // エラー

基本型

基本型には「整数」「実数」「テキスト」「真偽値」といったものが用意されており、それぞれにさらに複数の型があります。

整数

デフォルトの型はInt型です。
以下のように変数を宣言すると型推論によりInt型になります。

例)

var num = 100 // numはInt型になります

Int型は実行されるCPUによって32bitもしくは64bitのデータ幅になります。
実際の整数の型にはビット数に応じて以下のものが用意されています。

説明
Int8 符号付き8bit
Int16 符号付き16bit
Int32 符号付き32bit
Int64 符号付き64bit
UInt8 符号なし8bit
UInt16 符号なし16bit
UInt32 符号なし32bit
UInt64 符号なし64bit

Int / UInt は、使われるプラットホームによって変わります。

  • 32bit プラットホーム : Int = Int32 , UInt = UInt32
  • 64bit プラットホーム : Int = Int64 , UInt = UInt64

例)

var num1:Int8 = 12          // Int8型
var num2:Int16 = 123        // Int16型
var num3:Int32 = 123456     // Int32型
var num4:Int64 = 12345678   // Int64型

また、8bit幅の整数型としてByte型がありますが、これはInt8と同じ型です。これは、おなじ型が2つあるわけではなく、ByteはInte8のTypeAliasなのです。

typealias Byte = UInt8

Swiftでは、型に別名を付けられるようになっており、Swiftの型にはさまざまなTypeAliasが付けられ、用意されています。
Int8のエイリアス「Byte」はありますが、UInt8のエイリアス「UByte」なるものはありません。

実数 (不動小数)

浮動小数は値を小数に10の何乗をかけたかで表現します。
例えば123なら、「1.23に10の2乗」と表します。このとき仮数は1.23、指数は2乗となります。
浮動小数は「符号」、「指数」、「仮数」のそれぞれのデータをメモリに保管して値を表します。
デフォルトはFloatです。

浮動小数の型は以下のようなものがあります。

説明
Float 32bitの浮動小数
Double 64bitの浮動小数
Float80 80bitの浮動小数
Float96 96bitの浮動小数

例)

var num5:Float = 1.234          // Float型
var num6:Double = 1.23456       // Double型
var num7:Float80 = 1.2346       // Float80型
var num8:Float96 = 1.2346       // Float96型

なお、Float32はFloat、Float64はDoubleのTypeAliasです。

typealias Float32 = Float

typealias Float64 = Double

テキスト

テキストを扱う型です。デフォルトはString型です。

説明
String テキストを扱う
Character 1文字のテキストを扱う(Swiftではあくまでもテキスト)

例)

var name1 = "Neko"            // String型
var name2:String = "Neko" // String型
var name3:Character = "N" // Character型

真偽

Boolを使用します。

説明
BOOL 真偽値をあつかう(trueもしくはfalse)

例)

var flag:Bool = true

Booleanも似ているけど注意

SwiftにはBooleanという型も用意されています。BooleanはInt8のType Aliasです。
Objective-Cの真偽で使う0、1の互換性のために用意されていると思われます。
しかし、Swiftの真偽はBoolを使うため、間違わないようにする必要があります。

その他の型

他にもいろいろと型はありますが、後述します。

コメントの書き方

一行

// 1行コメント

複数行

/*
ここにコメントを書く
*/
/*
    /*
    階層化のコメントOK
    */
*/

Swift勉強1 リテラル

Swiftで用意されているリテラル(値を直接表記する際の書式)については以下のようなものがあります。

数値

数値をそのまま記述する形になります。

123 //数値
12.3 //小数

3桁区切り表示が便利!

長い数字の場合、例えば1,234,567,890 のように3桁区切りで表記しますが、Swiftでは,の変わりに_で同じように区切り、わかりやすい表記にできます。これは1234567890と同じ扱いになります。

1_234_567_890 //1234567890と同じ
001_234_567_890 //1234567890と同じ

数値のリテラルの型は何になるか?

  • 整数リテラル->Int型
  • 実数リテラル(少数やEをつかった桁数の多い値など)-> Doubule型

10進数以外の記述

2進数

prefixに「0b」(数字のゼロに小文字英字b)を付けて記述します。

0b1011

8進数

prefixに「0o」(数字のゼロに小文字英字o)を付けて記述します。

0o1376

16進数

prefixに「0x」(数字のゼロに小文字英字x)を付けて記述します。

0xFF
0x11BB

指数表現

10のn乗には「e」(もしくは「E」)を使う

桁数が多い値の場合、10のn乗を示す「e」もしくは「E」記号を使って記述することができます。(2,8,10,16進数で使えます)

1.234e5 // 1.234×10の5乗 = 123400のこと

2のn乗には「p」(もしくは「P」)を使う

2のn乗を「p」もしくは「P」記号を使って記述することができます。
以下の例は今度は16進数にしています。(2,8,10,16進数で使えます)

0x10p2 // 16×2の2乗 = 64 = 0x40のこと

##テキスト
テキストはダブルクォート「”」を付けて記述します。

"Hello, world!"

エスケープ文字

直接記述することができない文字はエスケープ文字で記述します。

エスケープ文字 説明
\” ダブルクォート(”)
\ バックスラッシュ(\)
\t 水平タブ
\r キャリッジリターン
\n ラインフィード
ヌル文字

以下のように記述して、Xcodeのメニューからoption+xommand+returnでアシスタントエディターを表示し、コンソールアウトプットで確認できます。

println("Hello!r I am "Neko".")

変数の埋め込みには()を使う

変数に代入されているテキストの埋め込みは以下のように「()」内に変数を入れて記述します。

var name = "Neko"
println("name = (name)")

// name = Neko

真偽

Objective-Cでは「YES」、「NO」でしたが、Swiftでは「true」、「false」で記述します。

true
false