20211011のSwiftに関する記事は4件です。

縦にページングするScrollViewを作成(UIScrollView)

今回の内容 コードと簡単解説 まずは、.isPagingEnabledをtrueで設定して、ページングを可能にします。 .contentSizeでスクロールするサイズを設定します。今回は、縦にだけスクロールさせるので、widthをview.frame.widthで設定します。 contentSizeにheight: view.frame.height * 3を設定して、y軸方向に3段階のぺージングをする様にします。 import UIKit class ViewController: UIViewController { let scrollView = UIScrollView() override func viewDidLoad() { super.viewDidLoad() scrollView.frame = CGRect(x: view.frame.minX, y: view.frame.minY, width: view.frame.width, height: view.frame.height) scrollView.contentSize = CGSize(width: view.frame.width, height: view.frame.height * 3) scrollView.isPagingEnabled = true scrollView.backgroundColor = .systemIndigo view.addSubview(scrollView) let topLabel = UILabel(frame: CGRect(x: scrollView.frame.maxX / 4, y: scrollView.frame.maxY / 10, width: scrollView.frame.width / 2, height: scrollView.frame.height / 20)) topLabel.text = "Top" topLabel.font = UIFont.boldSystemFont(ofSize: 25) topLabel.textColor = .white topLabel.textAlignment = .center scrollView.addSubview(topLabel) let centerLabel = UILabel(frame: CGRect(x: scrollView.frame.maxX / 4, y: scrollView.frame.maxY + scrollView.frame.maxY / 10, width: scrollView.frame.width / 2, height: scrollView.frame.height / 20)) centerLabel.text = "Center" centerLabel.font = UIFont.boldSystemFont(ofSize: 25) centerLabel.textColor = .white centerLabel.textAlignment = .center scrollView.addSubview(centerLabel) let bottomLabel = UILabel(frame: CGRect(x: scrollView.frame.maxX / 4, y: (scrollView.frame.maxY * 2) + scrollView.frame.maxY / 10, width: scrollView.frame.width / 2, height: scrollView.frame.height / 20)) bottomLabel.text = "Bottom" bottomLabel.font = UIFont.boldSystemFont(ofSize: 25) bottomLabel.textColor = .white bottomLabel.textAlignment = .center scrollView.addSubview(bottomLabel) } } 終わり ご指摘、ご質問などありましたら、コメントまでお願い致します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スクロールしたら画像が拡大するやつ〜

(※この記事は、storyboardにスクロールビューを貼る基礎知識がある人を前提にしています。) 今回は、スクロールビューを上にスクロールしたら(下に引っ張ったら)、画像(ヘッダー画像)が拡大するやつを実装していきたいと思います。 こんな感じのやつです↓ (少しカクついてますが、実際ビルドするとちゃんとなめらかに動きます) ちなみに今回の方法は、結構いろんな方々が記事として既に投稿してますが、僕のはその中でも一番シンプルな方法だと思います。 なので、「もっと詳しく理解したい!」という方は、他の記事を参考にしていただければと思います。 ではいきましょう! はじめに ①ではまず、スクロールビューを用意しましょう ②そしてその上に、拡大させたいビューを置いてください そうすると、こんな感じになります。 scrollViewと拡大させるImageViewの間にviewを入れるのも忘れずに〜 コード ではコードに移ります。 まずは、完成型から import UIKit class ViewController: UIViewController { @IBOutlet weak var scrollView : UIScrollView! @IBOutlet weak var expansionImageView : UIImageView! private var frameHeight : CGFloat! override func viewDidLoad() { super.viewDidLoad() scrollView.delegate = self frameHeight = self.expansionImageView.frame.size.height } } extension ViewController : UIScrollViewDelegate{ func scrollViewDidScroll(_ scrollView: UIScrollView) { let offsetY = scrollView.contentOffset.y if offsetY < 0{ let ToPlusOffsetY = offsetY * -1 let newY = ToPlusOffsetY * -1 let newHeight = ToPlusOffsetY + frameHeight expansionImageView.frame = CGRect(x: 0, y: newY, width: view.frame.size.width, height: newHeight) } } } では解説していきます。 当たり前ですが、まずはさきほどstoryboardで設定したオブジェクト達をこのコントローラーに繋げてください。 そして、そのスクロールビューが持つメソッドである「ScrollViewDidScroll」を呼び出してください。これは、スクロールビューがスクロールしたときに呼ばれるメソッドです。 ※あ、デリゲートを自分に委任することも忘れずに。順番的には、委任先を指定⇨メソッドを呼ぶがベターだと思います。 ちなみに、「スクロールビュー」というのは、TableViewやCollectionViewも自動的に保持しているものですので、明示的にScrollViewそれ自体に拘らなくても大丈夫です。 そして、scrollViewDidScrollの中に、スクロールビューが移動する量を「offsetY」という変数として持たせます。 この「scrollView.contentOffset.y」というのは、「縦方向にどれだけ移動したか」という意味です。 逆に「scrollView.contentOffset.x」であれば、「横方向にどれだけ移動したか」になります。 そして、その変数が0以下になれば、つまり「縦方向にどれだけ移動したか(縦方向に移動した移動量)が、0以下になれば(上に行けば)」、という構文をif分で作ります。 ※「y」は、上に行けば行くほどマイナスの値になります。 そしてその中で、まずは取得した移動量をプラスに変換する変数(ToPlusOffsetY)を準備します。 さらに、それをもう一度マイナスの値に変換して変数として持たせます。(Yをさらに上に動かすため) 次に、さきほど定義したToPlusOffsetYと、グローバルにすでに持たせているframeHeight(画像の現在の縦サイズ)を足して、変数化します。 そして最後に、拡大させたい画像のサイズに、newYやnewHieghtを含めた新しいサイズを代入します。 こうすることで、思うように動くようになると思います。 最後に シンプル過ぎてすみませんでした!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSアプリ開発のための外部ライブラリのリンクの種類や配布/利用方法

はじめに iOSアプリ開発用パッケージマネージャーごとのStatic/Dynamicリンク設定とカスタマイズおよび各種調査方法について整理したのですが、スタティックとかダイナミックリンクってなんなのよ、ということもあるので、その前提知識としてiOSアプリ開発のための外部ライブラリのリンクの種類や配布/利用方法についても整理しておきます。 この記事では大きく分けて下記の2つのことを説明します 外部ライブラリのリンク種類 スタティックリンク ダイナミックリンク 外部ライブラリの配布/利用方法 Library Framework XCFramework そしてこれは例えば、"スタティックリンクのFramework"や"ダイナミックリンクのFramwork"の組み合わせが存在するということです。 用語としてややこしいのは外部ライブラリの配布方法にLibraryとFrameworkがあることです。この記事では外部ライブラリと書いた場合、スタティック/ダイナミック関係なくLibrary/Frameworkの区別はしません。具体的には外部ライブラリ-> SVProgressHUD みたいなノリです。 私自身が勘違いしている可能性も高いし、もっといいまとめ方もあるかもしれないのでそれはそれでコメントか別にアウトプットしてもらえればありがたいです。 外部ライブラリリンクの種類 Appleの昔のドキュメントから 主にOSX用のドキュメントですが、スタティックリンクについて下記のように図示されています。 上記、重要なのはApplication codeの中にStatic librariesが含まれるということ。逆に下記で示されるダイナミックリンクではApplication codeにはDynamic library refrencesを含み、そのライブラリの実体はアプリとは別ファイルとして保持します。 上記Appleドキュメントを読むと、「ダイナミックリンクのライブラリは本体アプリサイズを抑える」 ことなどの解決策として存在するのがわかります。これは例えばUIがあるアプリはUIKit.frameworkとかをiOS側に持っておけば各アプリはそれを参照さえすればいいわけです。iOS 13からのSwiftUI.frameworkでもそうでしょう。iOS 13からiOS側でSwiftUIのフレームワークを持っているからiOS 13からSwiftUIを使える。 しかしiOSアプリとして我々がアプリ利用者に配布する際は外部ライブラリをダイナミックリンクとしても利用者がダウンロードする全体のアプリサイズは外部ライブラリを含んでいるので上記のドキュメントの 「ダイナミックリンクのライブラリは本体アプリサイズを抑える」 記述はしっくりくる理由にはなっていないのがわかります。 macOSでAtom.appを覗いてみる ダイナミックリンクのライブラリについて想像しやすくするため、macOSのAtom.appの中を見てみます。 libffmpet.dylibやlibnode.dylibなどが同梱されており、これがダイナミックリンクされている、ということでしょう。iOSアプリに限らず、ダイナミックリンクのライブラリを同梱するのであればAtom.appのサイズは大きいのでこれ良い具体例ではないかもしれませんがニュアンスわかるでしょうか。これらのダイナミックリンクライブラリがmacOSにあってそこを参照するならたしかにアプリサイズはその分だけ小さくて済むはずです。 2つのリンク手段 外部ライブラリリンクの種類としてダイナミックとスタティックあるので2つの概要を整理します ダイナミックリンクライブラリ 概要 必要なときにロードする アプリの起動時またはランタイムにロードすることができる iOSアプリだと起動時になるのは? Dynamicローダ 起動時にアプリが実際に使用する外部シンボルのみを解決 別名 Dynamic Shared Libraries shared objects Dynamically Lindked Libraries メリット アプリのファイルサイズとメモリフットプリントの削減 動作 Heap領域にDynamic Library Refrencesを持つ Dynamic Libraryのファイル自体は別途保持 スタティックリンクライブラリ 概要 スタティックリンカーを使ってリンクするとライブラリが実行ファイルにコピーされる スタティックリンカー オブジェクトコードを実行時に全体をメモリにロードする オブジェクトコードとは コンパイル済みのソースコードとライブラリコード 別名 Static archive Libraries Statick Lindked Shared Libraries 動作 アプリ起動時にアプリ自体のコードとリンクされているStaticライブラリのコードを含めてアドレス空間に読み込まれる ヒープ領域でアプリ自体と一つのファイルになっている(.appに組み込まれている) 混乱しそうなのはスタティックリンクは起動時に時間かかりそうだけど、ビルドの後半でスタティックリンカーによって、アプリと一体になっているからアプリ起動時間にダイナミックリンクに比べたら遅くなる要因は少ない ライブラリ配布/利用手段 Library 外部ライブラリリンクの種類 スタティックリンク ダイナミックリンク 実体 ビルド済みのソースコード Framework 外部ライブラリリンクの種類 スタティックリンク ダイナミックリンク 実体 ビルド済みのソースコード、画像リソース、ローカライズされた文字列、ヘッダー、リファレンス 例 Foundation.framework UIKit.framework SwiftUI.framework XCFramework 実体 複数CPUアーキテクチャ別のFrameworkを1つにまとめたもの 経緯 だいたいの経緯がわかってると、なぜこんな種類があるのかなんとなくわかるはずですので書いてみます。 2014 Xcode 6でiOS 8からダイナミックリンクのFrameworkをサポートした おそらく ダイナミックリンクのLibraryも同時にサポートされた? もともとはセキュリティ上の懸念があってできなかった? iOS 8からAppのExtensionが導入されたため懸念を払拭してやらざるを得なくなった? Embedded Frameworkもだいたいこのあたり 2015 Xcode 7でiOS 9からBitcodeが対応 2019 Xcode 11(WWDC19)あたりでXCFrameworkが登場 Xcode 11からSwift Package ManagerがXcodeのGUIから設定できるようになった 2020 Swift Package ManagerでXCFramework形式の配布ができるようになった 2021 Carthage v0.37.0 --use-xcframeworksを使ってXCFramework化 CocoaPods v1.9.0 XCFramework対応 https://blog.cocoapods.org/CocoaPods-1.9.0-beta/ おわりに 冒頭で組み合わせとしてスタティックリンクされたFrameworkがある、と書いてはいますが、これ昔のAppleのFrameworkに関するドキュメントを見るとFrameworkの説明としてダイナミックリンクの説明とそのメリットについて述べています。つまり、スタティックリンクなFrameworkは昔は存在しなかったのかなと思います。なぜならFrameworkのLibraryに比べたメリットはリソースを持てることだからですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

タップさせて吹き出しをpopさせる。

まずはpopさせるクラスを用意する class PopViewController:UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemOrange } } 遷移前の画面でコード作成。 //遷移先のVCをインスタンス化 let viewController = PopViewController() //popoverで表示するViewController //遷移方法をpopover viewController.modalPresentationStyle = .popover //吹き出しのサイズを設定する viewController.preferredContentSize = CGSize(width: 200, height: 150) let presentationController = viewController.popoverPresentationController //up 吹き出しを表示させる向きを設定する presentationController?.permittedArrowDirections = .up //どこを基準に表示させるかのsourceViewを設定 presentationController?.sourceView = cell //吹き出しを表示させる位置を設定。 presentationController?.sourceRect = cell.bounds //popoverさせるためのdelegateメソッド viewController.presentationController?.delegate = self present(viewController, animated: true, completion: nil) 必要なdelegateメソッドを用意 class ViewController: UIViewController, UIPopoverPresentationControllerDelegate{ //Iphoneで表示させる際のdelegateMethod func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { return .none } } どこかで関数を発火すればOK!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む