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

ビューの中に配置してあるあるボタンだけタップイベントを拾いたいことがあります。
単に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が入る