
まずApple IDを取得する。
→持ってる。
Xcodeをインストールする
→入れたぞ。
もくじ
Swiftの型
- Int型
整数型 - UInt型
符号なし整数。普通はInt型を利用する - Float型
実数型。小数点を含むものに利用します、有効桁数7桁 - Double型
実数型。小数点を含むものに利用します、有効桁数16桁 - String型
文字列型 - Bool型
真偽値を扱う。
シミュレータを起動してHello World
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// (1) ラベルに文字を入れる
outputLabel.text = "Hello Swift!"
}
@IBOutlet weak var outputLabel: UILabel!
}
→できたぞ。
じゃんけんアプリつくるぞ!
じゃんけん画像の素材
https://drive.google.com/file/d/1OfAkCAU47v1DZ5gPxjh-V35DH3eWN2e9/view
Control + パーツをソースコードにドラッグアンドドロップで関連づけができる。

//
// ViewController.swift
// MyJanken
//
// Created by 金広優 on 2020/02/14.
// Copyright © 2020 Swift-Beginners. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var answerImageView: UIImageView!
@IBOutlet weak var answerLabel: UILabel!
// じゃんけん (数字)
var answerNumber = 0
@IBAction func shuffleAction(_ sender: Any) {
if answerNumber == 0 {
answerLabel.text = "グー "
answerImageView.image = UIImage(named: "gu")
} else if answerNumber == 1 {
answerLabel.text = "チョキ "
answerImageView.image = UIImage(named: "choki")
} else if answerNumber == 2 {
answerLabel.text = "パー "
answerImageView.image = UIImage(named: "pa")
}
// 次のじゃんけんへ
answerNumber = answerNumber + 1
}
}
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var answerImageView: UIImageView!
@IBOutlet weak var answerLabel: UILabel!
// じゃんけん (数字)
var answerNumber = 0
@IBAction func shuffleAction(_ sender: Any) {
answerNumber = Int.random(in: 0..<3)
if answerNumber == 0 {
answerLabel.text = "グー "
answerImageView.image = UIImage(named: "gu")
} else if answerNumber == 1 {
answerLabel.text = "チョキ "
answerImageView.image = UIImage(named: "choki")
} else if answerNumber == 2 {
answerLabel.text = "パー "
answerImageView.image = UIImage(named: "pa")
}
}
}

import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var answerImageView: UIImageView!
@IBOutlet weak var answerLabel: UILabel!
// じゃんけん (数字)
var answerNumber = 0
@IBAction func shuffleAction(_ sender: Any) {
var newAnserNumber = 0
repeat {
newAnserNumber = Int.random(in: 0..<3)
} while answerNumber == newAnserNumber
answerNumber = newAnserNumber
if answerNumber == 0 {
answerLabel.text = "グー "
answerImageView.image = UIImage(named: "gu")
} else if answerNumber == 1 {
answerLabel.text = "チョキ "
answerImageView.image = UIImage(named: "choki")
} else if answerNumber == 2 {
answerLabel.text = "パー "
answerImageView.image = UIImage(named: "pa")
}
}
}
アイコンについて
1枚の画像から複数のアイコンを設定してくれるMakeAppIconというツールを利用する。
音楽アプリをつくろう


SimulatorはCommand + 矢印キーで横にしたり、回転できる。

音源のサンプルをドラッグアンドドロップでセットする。
AVFoundationを読み込む
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// シンバルの音源ファイルを指定
let cymbalPath = Bundle.main.bundleURL.appendingPathComponent("cymbal.mp3")
// シンバル用ぷのプレイヤーインスタンスを作成
var cymbalPlayer = AVAudioPlayer()
@IBAction func cymbal(_ sender: Any) {
}
}

import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// シンバルの音源ファイルを指定
let cymbalPath = Bundle.main.bundleURL.appendingPathComponent("cymbal.mp3")
// シンバル用のインスタンス作成
var cymbalPlayer = AVAudioPlayer()
@IBAction func cymbal(_ sender: Any) {
do {
// シンバル用のプレイヤーに、音源ファイル名を指定
cymbalPlayer = try AVAudioPlayer(contentsOf: cymbalPath, fileTypeHint: nil)
// シンバルの音源再生
cymbalPlayer.play()
} catch {
print("🐱シンバルでエラーが発生したにゃん!")
}
}
// シンバルの音源ファイルを指定
let guitarPath = Bundle.main.bundleURL.appendingPathComponent("guitar.mp3")
// シンバル用のインスタンス作成
var guitarPlayer = AVAudioPlayer()
@IBAction func guitar(_ sender: Any) {
do {
// ギター用のプレイヤーに、音源ファイル名を指定
guitarPlayer = try AVAudioPlayer(contentsOf: guitarPath, fileTypeHint: nil)
guitarPlayer.play()
} catch {
print("🐱ギターでエラーが発生したにゃん!")
}
}
// BGMの音源ファイルを指定
let backmusicPath = Bundle.main.bundleURL.appendingPathComponent("backmusic.mp3")
// BGM用のインスタンス作成
var backmusicPlayer = AVAudioPlayer()
@IBAction func play(_ sender: Any) {
do {
// BGM用のプレイヤーに、音源ファイル名を指定
backmusicPlayer = try AVAudioPlayer(contentsOf: backmusicPath, fileTypeHint: nil)
backmusicPlayer.numberOfLoops = -1 // リピート設定
backmusicPlayer.play()
} catch {
print("🐱BGMでエラーが発生したにゃん!")
}
}
// Stopボタン
@IBAction func stop(_ sender: Any) {
// BGM停止
backmusicPlayer.stop()
}
}
リファクタリング
共通処理のsoundPlayer()を定義する
fileprivate func soundPlayer(player:inout AVAudioPlayer, path: URL, count: Int) {
do {
player = try AVAudioPlayer(contentsOf: path, fileTypeHint: nil)
player.numberOfLoops = count
player.play()
} catch {
print("エラーが発生したにゃん🐱")
}
}
共通関数で置き換える。
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// シンバルの音源ファイルを指定
let cymbalPath = Bundle.main.bundleURL.appendingPathComponent("cymbal.mp3")
// シンバル用のインスタンス作成
var cymbalPlayer = AVAudioPlayer()
@IBAction func cymbal(_ sender: Any) {
soundPlayer(player: &cymbalPlayer ,path:cymbalPath, count: 0)
}
// シンバルの音源ファイルを指定
let guitarPath = Bundle.main.bundleURL.appendingPathComponent("guitar.mp3")
// シンバル用のインスタンス作成
var guitarPlayer = AVAudioPlayer()
@IBAction func guitar(_ sender: Any) {
soundPlayer(player: &guitarPlayer ,path:guitarPath, count: 0)
}
// BGMの音源ファイルを指定
let backmusicPath = Bundle.main.bundleURL.appendingPathComponent("backmusic.mp3")
// BGM用のインスタンス作成
var backmusicPlayer = AVAudioPlayer()
@IBAction func play(_ sender: Any) {
soundPlayer(player: &backmusicPlayer ,path:backmusicPath, count: -1)
}
// Stopボタン
@IBAction func stop(_ sender: Any) {
// BGM停止
backmusicPlayer.stop()
}
fileprivate func soundPlayer(player:inout AVAudioPlayer, path: URL, count: Int) {
do {
player = try AVAudioPlayer(contentsOf: path, fileTypeHint: nil)
player.numberOfLoops = count
player.play()
} catch {
print("エラーが発生したにゃん🐱")
}
}
}
アクセス修飾子
- public
どこからでもアクセス可能 - internal
同じモジュール内のみアクセス可能 - fileprivate
ファイル内のみアクセス可能 - private
定義内の中でのみアクセス可能
地図アプリをつくる

Text Fieldを貼り付ける

Return KeyにSearchを設定

mapで検索してMap Kit Viewを選択する


Text FieldのConstraintを設定

Map kit Viewも同様に設定します。

Assistantを設定

Controlボタンを押しながらドラッグアンドドロップをします。

ConnectionをOutletに設定してConnect
Connectionの種別
- Outlet … そのUI部品をどこかで参照したい時
- Action … そのUI部品の動作を決めたい時
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var inputText: UITextField! // ←● 追加された
}

Map kit Viewも同様に設定します。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var inputText: UITextField!
@IBOutlet weak var dispMap: MKMapView!
}
MapKitをimport
import UIKit
import MapKit // ←● 追加
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var inputText: UITextField!
@IBOutlet weak var dispMap: MKMapView!
}

import UIKit
import MapKit
class ViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Text Fieldのdelegate通知先を設定
inputText.delegate = self
}
@IBOutlet weak var inputText: UITextField!
@IBOutlet weak var dispMap: MKMapView!
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// キーボードを閉じる
textField.resignFirstResponder()
// 入力された文字を取り出す(2)
if let searchKey = textField.text {
// 入力された文字をデバッグエリアに表示(3)
print(searchKey)
}
return true
}
}
viewDidLoad()は画面が描画された時に最初に実行されるメソッド。

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// キーボードを閉じる(1)
textField.resignFirstResponder()
// 入力された文字を取り出す(2)
if let searchKey = textField.text {
// 入力された文字をデバッグエリアに表示(3)
print(searchKey)
}
// デフォルトで動作を行うのでtrueを返す(4)
return true
}
検索を押したらキーボード閉じればOK
このコードあるから入力後にキーボードが閉じられる。
textField.resignFirstResponder()
textFieldShouldReturn()は予め規定されているdelegateメソッド。
Xcodeを日本語化していないことに気づく
緯度経度を取得して表示

import UIKit
import MapKit
class ViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Text Fieldのdelegate通知先を設定
inputText.delegate = self
}
@IBOutlet weak var inputText: UITextField!
@IBOutlet weak var dispMap: MKMapView!
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// キーボードを閉じる(1)
textField.resignFirstResponder()
// 入力された文字を取り出す(2)
if let searchKey = textField.text {
// 入力された文字をデバッグエリアに表示(3)
print(searchKey)
// CLGeocoderインスタンスを取得(5)
let geocoder = CLGeocoder()
// 入力された文字から位置情報を取得
geocoder.geocodeAddressString(searchKey, completionHandler: { (placemarks, error) in
// 位置情報が存在する場合は、unwrapPlacemarksに取り出す(7)
if let unwrapPlacemarks = placemarks {
// 1件目の情報を取り出す(8)
if let firstPlacemark = unwrapPlacemarks.first {
// 位置情報を取り出す(9)
if let location = firstPlacemark.location {
// 位置情報から緯度経度をtargetCordinateに取り出す(10)
let targetCoordinate = location.coordinate
// 緯度経度をデバッグエリアに表示(11)
print(targetCoordinate)
}
}
}
})
}
// デフォルトで動作を行うのでtrueを返す(4)
return true
}
}
住所などの文字列から位置情報を取得するメソッド
geocoder.geocodeAddressString(searchKey, completionHandler: { (placemarks, error) in
// 以下略
})
クロージャが利用されていて、位置情報が取得できたタイミングで{}内が動きます。

import UIKit
import MapKit
class ViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Text Fieldのdelegate通知先を設定
inputText.delegate = self
}
@IBOutlet weak var inputText: UITextField!
@IBOutlet weak var dispMap: MKMapView!
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// キーボードを閉じる(1)
textField.resignFirstResponder()
// 入力された文字を取り出す(2)
if let searchKey = textField.text {
// 入力された文字をデバッグエリアに表示(3)
print(searchKey)
// CLGeocoderインスタンスを取得(5)
let geocoder = CLGeocoder()
// 入力された文字から位置情報を取得(6)
geocoder.geocodeAddressString(searchKey, completionHandler: { (placemarks, error) in
// 位置情報が存在する場合は、unwrapPlacemarksに取り出す(7)
if let unwrapPlacemarks = placemarks {
// 1件目の情報を取り出す(8)
if let firstPlacemark = unwrapPlacemarks.first {
// 位置情報を取り出す(9)
if let location = firstPlacemark.location {
// 位置情報から緯度経度をtargetCordinateに取り出す(10)
let targetCoordinate = location.coordinate
// 緯度経度をデバッグエリアに表示(11)
print(targetCoordinate)
// ピンを生成(12)
let pin = MKPointAnnotation()
// ピンの置く場所に緯度経度を設定(13)
pin.coordinate = targetCoordinate
// ピンのタイトルを設定(14)
pin.title = searchKey
// ピンを地図を置く(15)
self.dispMap.addAnnotation(pin)
// 緯度経度を中心にして半径500mの範囲を表示(16)
self.dispMap.region = MKCoordinateRegion(center: targetCoordinate, latitudinalMeters: 500.0, longitudinalMeters: 500.0)
}
}
}
})
}
// デフォルトで動作を行うのでtrueを返す(4)
return true
}
}
アンラップ
if let 変数名 = ターゲット
if let searchKey = textField.text {
}
textField.textの値がsearchKey変数に代入できたら … 値があるなら {}を実行
delegate
- クラスで行いたい処理の一部を他のクラスに任せる
- 任せた処理を指定したクラスに通知
仲介する仕組み🐱✨
登場するもの
- ①処理を依頼するクラス
ViewController
・UITextFieldクラスから作ったインスタンスのinputTextに対して、「inputText.delegate = self」と記述してdelegateの通知先を自分自身と設定。
・通知したい内容はtextFieldShoudReturnメソッドを指定している - ②依頼する、依頼されるクラスを仲介するプロトコル
UITextFieldDelegate
検索キーワードが入力されてReturn(Search)が押された時の情報を取得して、通知先がViewControllerであることをUITextFieldに教える - ③処理を依頼されるクラス
UITextField
・UITextFieldDelegateから通知を受けたら、UITextFieldは、View Controllerに「return」がタップされた時の情報を教える
マップの種別を切り替え

Buttonを選択してドラッグアンドドロップ

ButtonのTypeをDetail Disciosureに設定

Constraintを右端になるように設定


Actionを指定してConnect
・・・
}
// デフォルトで動作を行うのでtrueを返す(4)
return true
}
@IBAction func changeMapButton(_ sender: Any) {
}
}
トグルボタンにする
// デフォルトで動作を行うのでtrueを返す(4)
return true
}
@IBAction func changeMapButton(_ sender: Any) {
// mapTypeプロパティ一値をトグル
// 標準 → 航空写真 → 航空写真+標準
// 3D Flyover → 3D Flyover+標準
// → 交通機関
if dispMap.mapType == .standard {
dispMap.mapType = .satellite
} else if dispMap.mapType == .satellite {
dispMap.mapType = .hybrid
} else if dispMap.mapType == .hybrid {
dispMap.mapType = .satelliteFlyover
} else if dispMap.mapType == .satelliteFlyover {
dispMap.mapType = .hybridFlyover
} else if dispMap.mapType == .hybridFlyover {
dispMap.mapType = .mutedStandard
} else {
dispMap.mapType = .standard
}
}


![[MySQL] rangeが絡むバッチサイズの計算](https://www.yuulinux.tokyo/contents/wp-content/uploads/2020/04/mysql_logo-150x150.jpg)

