20210411のSwiftに関する記事は5件です。

[初心者向け] Main.storyboardを消してViewControllerごとにStoryboardを作る

はじめに XCodeでプロジェクトを作成すると必ず存在するMain.storyboard。 今回はMain.storyboardにViewControllerをいくつも置いて開発をしている初学者向けにこの記事を書きました。 なぜMain.storyboardを消すのか デフォルトで入っているものだし、画面遷移の流れを追いやすいのになぜ消す必要があるのか、と私も最初は思っていました。 一般的にチームで開発を行う場合、何人もの人が同時にプロジェクトを編集します。 その際全員が別のViewControllerをいじっていたとしても、そのViewControllerが全てMain.storyboard上にあったらマージする時にコンフリクトが起きてしまう可能性が高いのです。 その対策としてViewControllerとstoryboardを一対一で作成している企業が多いようです。 これなら複数人でブランチを切って開発を進めていっても該当するstoryboard内でしかコンフリクトは起きませんよね。 では実際にやってみましょう。 環境 ・macOS Big Sur バージョン11.2.3 ・XCode 12.4 ・Swift5.3.2 ① Main.storyboardを削除 Move to trashしちゃってください。 元からあるViewControllerも不要なのでMove to trash ② 新しくstoryboardとViewControllerを作成 File → New Fileからstoryboardを作成し、ViewControllerを配置します。 Is initial ViewControllerにチェックを入れるのを忘れずに! ③ Info.plistからMainを削除 今のままでは起動経路がMain.storyboardになっているので、その記述を削除します。 Info.plist内のMainと書いてあるものを−ボタンを選択して消してください。 ④ SceneDelegateで起動経路を設定 アプリ起動時の初期画面を条件に応じて切り替えたり、初回起動時に何かしたい場合に対応するため、SceneDelegateで起動経路を設定します。 Project→GeneralのMain InterfaceのMainと書かれている箇所を新しく作成したViewControllerにすることでも起動経路を設定できますが、SceneDelegateで設定する場合はこちらは使用しないので削除して空欄にしてください。 次に、SceneDelegateに以下のようにコードを書きます。 SceneDelegate.Swift import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } //Windowをインスタンス化 window = UIWindow(windowScene: windowScene) //rootViewControllerに指定したいControllerを指定 //StoryboardからViewControllerを生成 window?.rootViewController = UIStoryboard(name: "FirstView", bundle: nil).instantiateInitialViewController() window?.makeKeyAndVisible() } 以上で完了です。実行すると指定したViewControllerが表示されるはずです。 他の画面もStoryboardとViewControllerを一対一で作成し、コードで画面遷移を行うと便利です! segueを使って画面遷移をしたい場合はStoryboardReferenceを使用すると良いです。 参考記事 【Swift】プロジェクト作成時に生成されるMain.storyboardを削除する Xcode 11でStoryboardを使わずに開発する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SwiftUIを始めてみました

iPhoneアプリに挑戦しようと思って、最近お仕事でStoryboardを用いてアプリを作っています。ただ、いつまでもStoryboardでアプリを作るのも色々大変なので思い切ってSwiftUIの勉強を独学しています。今回は(?)大したことを書いてないのでキャプチャで書いていきます。 まずは初期のソースを色々いじってみることに SwiftUIプロジェクトの初期ソースがこれです。SwiftUIからはソースをリアルタイムにプレビューできるので便利ですね。 そして理想のアプリを作るためにソースをいじってみることに。なんだかんだプログラムは割と触ってきたので、「Text」という部分をもう一個下にコピペすれば「Hello, world!」が2行出来るんじゃないかと予測。早速コピペしてみると いやいや、なんで画面が2画面出るんだよ・・・?この時点で挫折しかけました。 (もし、2行にする場合は以下のようにVStackで囲めばいいらしい。) VStackで囲った箇所はVertical(垂直)に要素を並べるようです。何故VStackがないと2画面にバラけてしまうかはまだ調べきれてないですが・・・?これだというものがあったらまとめたいと思います。VStackの他にHStackやZStackみたいに囲えるものがあるのです。HTMLで言うところの「div」に近いなと思いました。最近HTMLをメインで仕事しているので個人的にはStoryboardより取っ付き易いなと思いました。また気が付いたことや作ったアプリについてまとめて行きたいと思います。 参考 https://swiftui.i-app-tec.com/ios/vstack-hstack.html https://developer.apple.com/documentation/swiftui/view https://tech.uzabase.com/entry/2019/06/05/141605
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】UICollectionViewCompositionalLayoutでレイアウトを組む

はじめに 今回はUICollectionViewCompositionalLayoutを使ってGridとInstagram風のレイアウトを組んでみたいと思います。 GitHub 以下のCollectionCompositeLayoutフォルダに今回のプロジェクトはあります。 カスタムセル実装 表示させるカスタムセルの背景色は以下のように設定しました。 CustomCollectionViewCell import UIKit final class CustomCollectionViewCell: UICollectionViewCell { static var identifier: String { return String(describing: self) } private let colors: [UIColor] = [.red, .blue, .green, .yellow, .orange, .cyan, .magenta ] override init(frame: CGRect) { super.init(frame: frame) contentView.backgroundColor = colors.randomElement() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } Gridレイアウト実装 まず、Gridの方から作ってみたいと思います。 GridViewController import UIKit final class GridViewController: UIViewController { @IBOutlet private weak var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() collectionView.collectionViewLayout = UICollectionViewCompositionalLayout( section: gridSection() ) collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.identifier) collectionView.dataSource = self } private func gridSection() -> NSCollectionLayoutSection { let itemCount = 3 let lineCount = itemCount - 1 let itemSpacing = CGFloat(2) let itemLength = (self.view.frame.size.width - (itemSpacing * CGFloat(lineCount))) / CGFloat(itemCount) //一つのitem let item = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(itemLength), heightDimension: .absolute(itemLength) ) ) //itemを三つ横並びに //.fractionalは親Viewとの割合 let items = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1) ), subitem: item, count: itemCount ) //item間のスペース items.interItemSpacing = .fixed(itemSpacing) //itemsが縦に並ぶグループを作成 let groups = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .absolute(itemLength) ), subitems: [items] ) //groupsからsectionを生成 let section = NSCollectionLayoutSection(group: groups) section.interGroupSpacing = itemSpacing return section } } extension GridViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 200 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCollectionViewCell.identifier, for: indexPath) as! CustomCollectionViewCell return cell } } Gridレイアウト解説 大切なところのみ解説したいと思います。 基本的な構成は以下の画像のようになっていて、Itemを決めてGroupを決めてSectionを決めてLayoutを設定すると言う流れになります。 それぞれ使う定数を事前に定義しておきます。 let itemCount = 3 let lineCount = itemCount - 1 let itemSpacing = CGFloat(2) let itemLength = (self.view.frame.size.width - (itemSpacing * CGFloat(lineCount))) / CGFloat(itemCount) 一つのアイテムのサイズを決めます。 absoluteとは絶対値と言う意味で、決まった値を幅にする設定にしています。 let item = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(itemLength), heightDimension: .absolute(itemLength) ) ) 次に、アイテムが三つ横並びになったグループを一つ作ります。 横並びのグループを作りたいので、horizontalを指定しています。 fractionalWidthやfractionalHeightとは親Viewにたいしてどれぐらいの割合で幅を決めるかと言う意味です。親ビューと同じにしたいのであれば、1(100%)にします。70%にしたい場合は.fractionalWidth(7/10)や.fractionalWidth(0.7)のようにします。 subItemは先ほど作成したItemdです。それをitemCount(=3)個並べていると言う意味です。 let items = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1) ), subitem: item, count: itemCount ) これは先ほど作ったグループ(=items)にitemSpacing(=2)だけスペースを入れる設定をしています。 items.interItemSpacing = .fixed(itemSpacing) そして先ほど作成したグループ(=items)を縦に並べる設定をします。 縦に並べたいので、verticalにします。 let groups = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1), heightDimension: .absolute(itemLength) ), subitems: [items] ) groupsからsectionを作成し、スペースを開けます。 let section = NSCollectionLayoutSection(group: groups) section.interGroupSpacing = itemSpacing return section そして、最後にこの関数(func gridSection() -> NSCollectionLayoutSectionf)をcollectionViewに設定します。 collectionView.collectionViewLayout = UICollectionViewCompositionalLayout( section: gridSection() ) Instagram風レイアウト実装 次に、Instagram風レイアウトを組んでみたいと思います。先ほどのGridレイアウトより少し難しくなりますが、基本は同じです。 final class InstagramViewController: UIViewController { @IBOutlet private weak var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() collectionView.collectionViewLayout = UICollectionViewCompositionalLayout( section: instagramSection() ) collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.identifier) collectionView.dataSource = self } private func instagramSection() -> NSCollectionLayoutSection { let itemSpacing = CGFloat(2) let smallItemLength = (self.view.frame.size.width - (itemSpacing * 2)) / 3 let largeItemLength = smallItemLength * 2 + itemSpacing // 小itemが縦に2つ並んだグループ let smallItem = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(smallItemLength), heightDimension: .absolute(smallItemLength) ) ) let smallItemVerticalGroup = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(smallItemLength), heightDimension: .absolute(largeItemLength) ), subitem: smallItem, count: 2 ) smallItemVerticalGroup.interItemSpacing = .fixed(itemSpacing) // 小itemが縦に2つ並んだグループを横に3つ並べたグループ let smallItemsGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitem: smallItemVerticalGroup, count: 3 ) smallItemsGroup.interItemSpacing = .fixed(itemSpacing) // 大item + 小item*2 のグループ let largeItem = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(largeItemLength), heightDimension: .absolute(largeItemLength) ) ) let largeItemLeftGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitems: [largeItem, smallItemVerticalGroup] ) largeItemLeftGroup.interItemSpacing = .fixed(itemSpacing) let largeItemRightGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitems: [smallItemVerticalGroup, largeItem] ) largeItemRightGroup.interItemSpacing = .fixed(itemSpacing) // 各グループを縦に並べたグループ let subitems = [largeItemLeftGroup, smallItemsGroup, largeItemRightGroup, smallItemsGroup] let heightDimension = NSCollectionLayoutDimension.absolute( //sectionの間隔は50 largeItemLength * CGFloat(subitems.count) + (itemSpacing * 50) ) // 高さの計算は後に追加するスペース分も足す let groups = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: heightDimension), subitems: subitems ) groups.interItemSpacing = .fixed(itemSpacing) let section = NSCollectionLayoutSection(group: groups) section.interGroupSpacing = itemSpacing return section } } extension InstagramViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 200 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCollectionViewCell.identifier, for: indexPath) as! CustomCollectionViewCell return cell } } Instagram風レイアウト解説 こちらも大切のところのみ解説します。 今回はitemのサイズが異なるのでそれぞれ設定します。 let itemSpacing = CGFloat(2) let smallItemLength = (self.view.frame.size.width - (itemSpacing * 2)) / 3 let largeItemLength = smallItemLength * 2 + itemSpacing 小さいアイテムが縦に2つ並んだグループを作成しています。 let smallItem = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(smallItemLength), heightDimension: .absolute(smallItemLength) ) ) let smallItemVerticalGroup = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(smallItemLength), heightDimension: .absolute(largeItemLength) ), subitem: smallItem, count: 2 ) smallItemVerticalGroup.interItemSpacing = .fixed(itemSpacing) そして、そのグループを横に三つ並べたグループを作ります。 let smallItemsGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitem: smallItemVerticalGroup, count: 3 ) smallItemsGroup.interItemSpacing = .fixed(itemSpacing) 次に、左側に大きいアイテムと小さいアイテムの組み合わせ、右側に大きいアイテムと小さいアイテムの組み合わせのグループを作成しています。 let largeItem = NSCollectionLayoutItem( layoutSize: NSCollectionLayoutSize( widthDimension: .absolute(largeItemLength), heightDimension: .absolute(largeItemLength) ) ) let largeItemLeftGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitems: [largeItem, smallItemVerticalGroup] ) largeItemLeftGroup.interItemSpacing = .fixed(itemSpacing) let largeItemRightGroup = NSCollectionLayoutGroup.horizontal( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(largeItemLength) ), subitems: [smallItemVerticalGroup, largeItem] ) largeItemRightGroup.interItemSpacing = .fixed(itemSpacing) そして、作ったグループ三つを縦に並べたグループを作成します。 let subitems = [largeItemLeftGroup, smallItemsGroup, largeItemRightGroup, smallItemsGroup] let heightDimension = NSCollectionLayoutDimension.absolute( //sectionの間隔は50 largeItemLength * CGFloat(subitems.count) + (itemSpacing * 50) ) let groups = NSCollectionLayoutGroup.vertical( layoutSize: NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: heightDimension), subitems: subitems ) groups.interItemSpacing = .fixed(itemSpacing) 最後に、このグループを一つのセクションとして返します。 let section = NSCollectionLayoutSection(group: groups) section.interGroupSpacing = itemSpacing return section Gridの時と同じように、collectionViewに設定すればInstagram風のレイアウト完成です。 collectionView.collectionViewLayout = UICollectionViewCompositionalLayout( section: instagramSection() ) おわりに UITableViewがいらない日が来るかもしれませんね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】iOSアプリでタップ、ロングタップの認識をする方法

はじめに アプリでタップもしくは長押しの処理を行うにはUIGestureRecognizerのUITapGestureRecognizer(タップ)とUILongPressGestureRecognizer(長押し)を用います。 汎用性が高い上に比較的実装が簡単なので、自分が学習したことも含めまとめてみました。 開発環境 MacOS Big Sur version 11.2.3 Xcode12.4 Swift5.3.2 UITapGestureRecognizerとUILongPressGestureRecognizerの違い UITapGestureRecognizer 普通はタップ検知しない場所に置くことでイベントを検知する。 シングルタップ、ダブルタップなどのタップ数、タップした際の指の本数により対象を絞り込むことが可能 タップした際に検知されるため誤タップが起きやすい 以下から各条件の設定が可能 numberOfTouchesRequired 認識に必要な指の本数(デフォルト:1) numberOfTapsRequired 認識に必要なタップ数(デフォルト:1) buttonMaskRequired 認識のために押さなければならないボタンのビットマスク UILongPressGestureRecognizer ロングプレス(長押し)を検知する。タップを保持することでイベントが検知される。 長押しの継続時間、指の本数により絞り込むことが可能 以下から各条件の設定が可能 minimumPressDuration 認識に必要な長押しの時間(デフォルト:0.5) numberOfTouchesRequired 認識に必要な指の本数(デフォルト:1) numberOfTapsRequired 認識に必要なビューのタップ数(デフォルト:0) allowableMovement 指のずれを許容する範囲(デフォルト:10) タップ コード全文 import UIKit //UIGestureRecognizerDelegateを追加 class ViewController: UIViewController, UIGestureRecognizerDelegate { override func viewDidLoad() { super.viewDidLoad() //インスタンスの生成 let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(self.tapAction(_:)) ) //デリゲートをセット tapGesture.delegate = self //viewにtapGestureを追加 self.view.addGestureRecognizer(tapGesture) } //タップ時に実行されるメソッド @objc func tapAction(_ sender: UITapGestureRecognizer) { if sender.state == .ended { //タップ終了時の処理 } } } 解説 タップアクションのためのUIGestureRecognizerインスタンスを生成します let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(self.tapAction(_:)) ) デリゲートをセットし、ViewControllerのviewの上にtapActionをaddします tapGesture.delegate = self self.view.addGestureRecognizer(tapGesture) stateプロパティである.endedを用いてタップ終了時の処理を実装(ここでは空白) @objc func tapAction(_ sender: UITapGestureRecognizer) { if sender.state == .ended { } } 長押し 基本的にはタップのコードと同じ構造になります。 import UIKit //UIGestureRecognizerDelegate を追加 class ViewController: UIViewController,UIGestureRecognizerDelegate{ override func viewDidLoad() { super.viewDidLoad() //インスタンスを生成する let longPressGesture: UILongPressGestureRecognizer = UILongPressGestureRecognizer( target: self, action: #selector(self.longPressAction(_:)) ) //デリゲートをセット longPressGesture.delegate = self //viewにlongPressGestureを追加 self.view.addGestureRecognizer(longPressGesture) } //長押し時に実行されるメソッド @objc func longPressAction(_ sender: UILongPressGestureRecognizer) { if sender.state == .ended { //ここに、長押し終了時に実行したい処理を記載する } } } 複数のGestureの制御 タップや長押しに限らず複数のGesture認識の制御、同時認識、失敗の制御などを行う際にはUIGestureRecognizerDelegateのメソッドを用います。(例:一つのVCでシングルタップとダブルタップの認識をさせたい等) メソッド 制御 gestureRecognizerShouldBegin Gestureの認識の開始 shouldRecognizeSimultaneouslyWith Gestureの同時認識 shouldRequireFailureOf 競合のGestureによる自身のGestureの失敗 shouldBeRequiredToFailBy 競合のGestureに対する失敗の要求 shouldReceive touch Gestureのtouchの受け取り shouldReceive press Gestureのpressの受け取り 詳しくは参考にさせていただきましたこの記事がわかりやすいです ↓↓↓ よくわかるUIGestureRecognizerDelegate 終わりに UIGestureRecognizerには他にもPinch,Rotation,SwipeなどのGestureも存在するので、機会があればそちらも書こうと思います。 参考 UITapGestureRecognizerDelegate - UIKit | Apple Developer Documentation UILongPressGestureRecognizerDelegate - UIKit | Apple Developer Documentation UIGestureRecognizerDelegate - UIKit | Apple Developer Documentation よくわかるUIGestureRecognizerDelegate
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(Swift)世界一分かりやすく解説するdelegate(デリゲート)

意味不明の代表格Delegate Swiftをやる上で意味不明の代表格 デリゲートについて解説します。 まずは今回のテスト環境から説明します。 構成はこんな感じ。 デフォルトのMain.storuboardの初期画面にViewオブジェクトを追加。 その ViewのクラスにCustomViewクラスを割り当てている。 CustomView.xivにはCustomView.swiftファイルが割り当てられている。 もちろん、Viewオブジェクトは、ViewController.swiftファイルから扱えるようにGUIで紐付けをして、 CustomView.swiftファイルにも,Buttomオブジェクトのタップを感知できるようにGUIで紐付けてある。 画面を見るとこんな感じ。 ここで2つのSwiftファイルを見てみましょう。 CustomView.swift import UIKit //①プロトコルを宣言 protocol testDelegate: class{ //②関数名と引数の型を定義 func tappedSendButton(text: String) } class CustomView: UIView { var text = "これはCustomViewクラスのフィールド変数だよ" //②デリゲートを宣言 weak var delegate: testDelegate? // @IBAction func tappedtTestButton(_ sender: Any) { //④委任する関数を呼び出す。 delegate?.tappedSendButton(text: text) } //ここから下は、XivをViewに貼り付ける処理で今回のデリゲートの処理には関係ない override init(frame: CGRect){ super.init(frame: frame) self.configureView() } required init?(coder: NSCoder){ super.init(coder: coder) self.configureView() } private func configureView(){ guard let view = self.loadViewFromNib(nibName:"CustomView") else { return } view.frame = self.bounds self.addSubview(view) } } ViewController.swift import UIKit //testDelegateプロトコルを継承 class ViewController: UIViewController, testDelegate { @IBOutlet weak var testView: CustomView!    //④で呼び出された関数がViewControllerに委任されてるためtappedSendButton関数が呼び出される func tappedSendButton(text: String) { print(text) } override func viewDidLoad() { super.viewDidLoad() testViewオブジェクトの処理を自分自身(ViewController)に委任しますと宣言する。 testView.delegate = self } } ボタンをタップすると consoleに これはCustomViewクラスのフィールド変数だよ と表示される デリゲートとはつまり あるクラス(今回はController.swift)から、あるクラス(CustomView.swift)の関数を呼び出したい時に使う。 今回でいえば、ボタンがタップされたかどうかはCustomView.swiftでしか感知できないが、そこにデリゲートを追加してController.swiftに紐付いた関数を用意することでボタンがタップされた時に呼び出される関数から ControllerクラスのtappedSendButtonを呼び出すと言うことになる。 @IBAction func tappedtTestButton(_ sender: Any) { //ControllerクラスのtappedSendButton関数を呼び出す。 delegate?.tappedSendButton(text: text) } デリゲートのメリット 勘のいい人ならわかると思うがデリゲートも最大のメリットは クラス間で変数を自由に受け渡しができること 関数を呼ぶタイミングを任意のタイミングに調整できること だと思う。今回の場合で言えばもしCustomView.swiftで テキストフィールドを持っていたら、ボタンが押された瞬間のテキストフィールドをViewControllerに送る事ができる。 しかも、ボタンが押された瞬間と言う任意のタイミングで。 まとめ デリゲートとは関数の処理を他のクラスの関数に委任することなんだな。 書き方についてはこう言う風に書くんだな。と覚えましょう。 (書き方が難しすぎるからややこしくなってるだけ)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む