20210504のSwiftに関する記事は8件です。

Swift言語 一定の範囲内でループする数値

コピペ用 例えば 99 の次が 0 で, 逆に 0 の前が 99 のようにしたい時に使う。 増加: ... 97 < 98 < 99 < 0 < 1 < 2 ... 減少: ... 3 > 2 > 1 > 0 > 99 > 98 ... extension_Int.swift extension Int { /// looped value in range func looped(in range: ClosedRange<Self>) -> Self { let min = range.lowerBound let max = range.upperBound if self < min { return max - ((min - self - 1) % (max - min)) } else if max < self { return min + ((self - max - 1) % (max - min)) } else { return self } } } 使い方 一度ループを無視した計算をした後に、 .looped(in:) を使う 99 + 1 = 100 0 - 1 = -1 let a = 100.looped(in: 0...99) // a: 0 let b = (-1).looped(in: 0...99) // b: 99 さいごに 99 + 300 のように、ループが何周も回っている場合にも対応しています。 自動でループする型を作りたい人は @propertyWrapper と組み合わせれば良さそうですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Left side of mutating operator isn't mutable: 'self' is immutable

以下のようなクイズの問題と答え、何問目かを示すquestionNumberを関数で変化させようとしたら Left side of mutating operator isn't mutable: 'self' is immutable というエラーが発生した。 import Foundation struct QuizBrain { let quiz = [ Question(q: "1 + 2 = 3", a: "True"), ] var questionNumber = 0 } func nextQuestion() { if questionNumber + 1 < quiz.count { questionNumber += 1 } else { questionNumber = 0 } } } funcの前にmutatingを書くことでエラーは回避された。 どうやら構造体内の関数ではquestionNumberは不変のため変更できないようだ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】NWPathMonitorを使ったネットワーク監視方法について

本日内容 ライブラリを使わずにApple純正の方法(NWPathMonitor)で、Networkのハンドリングをできることが気がつきました。 今回はその時の手順を記載しております。 NWPathMonitor An observer that you use to monitor and react to network changes. ネットワークの変更を監視して対応するために使用するオブザーバー。 Availability iOS 12.0+ macOS 10.14+ Mac Catalyst 13.0+ tvOS 12.0+ watchOS 5.0+ Xcode 10.0+ 開発環境 Xcode 14.4 Swift iOS14以上 手順 1.Network.swiftを作り、下記を追加します。 import Network class Network { static let shared = Network() //シングルトン private let monitor = NWPathMonitor() func setUp() { monitor.pathUpdateHandler = { _ in } let queue = DispatchQueue(label: "Monitor") // ネットワーク監視開始 monitor.start(queue: queue) } func isOnline() -> Bool { return monitor.currentPath.status == .satisfied } } 2.AppDelegateに下記を参考に、Network.shared.setUp()を追加します func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Network.shared.setUp() // 初期化対応 return true } 3.ネットワークを実際に確認する場合 if Network.shared.isOnline { //ネットワークあり } else { //ネットワークなし } 今回は以上になります! これでネットワークErrorハンドリングして、ユーザー体験の向上にお役に立てればと存じます! 素敵な開発生活を! 最後まで読んでいただき、ありがとうございましたmm 参考資料 NWPathMonitorを使ったインターネット接続の確認方法 https://www.richcoding.co.jp/2020/03/26/nwpathmonitor/ NWPathMonitorのハマりどころ https://qiita.com/noppefoxwolf/items/55fafdea55de754d2b3d Apple公式 https://developer.apple.com/documentation/network/nwpathmonitor
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

StackViewのfillProportionallyが思い通りに動かなかった話

StackView.destributionわかったかも! 「StackViewのfillProportionallyちょっとわかったかも。要はStackViewの大きさと中身が揃ってない時中身の比を考慮して敷き詰めてくれるって感じね。Playgroundsでサンプル作って動かそ」 5つのUIViewを用意してwidthAnchorとheightAnchorをそれぞれを100pt×100ptにして、addArangeSubViewして。。。 import PlaygroundSupport import UIKit class View: UIView { let stackView = UIStackView() let redView = UIView() let orangeView = UIView() let yellowView = UIView() let greenView = UIView() let blueView = UIView() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white setupStackView() setupColorViews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupStackView() { stackView.backgroundColor = .white stackView.axis = .horizontal stackView.alignment = .fill stackView.distribution = .fillProportionally addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor), stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), stackView.widthAnchor.constraint(equalTo: self.widthAnchor) ]) } private func setupColorViews() { redView.backgroundColor = .red orangeView.backgroundColor = .orange yellowView.backgroundColor = .yellow greenView.backgroundColor = .green blueView.backgroundColor = .blue let colorViews: [UIView] = [redView,orangeView,yellowView,greenView,blueView] colorViews.forEach { view in NSLayoutConstraint.activate([ view.widthAnchor.constraint(equalToConstant: 100), view.heightAnchor.constraint(equalToConstant: 100) ]) stackView.addArrangedSubview(view) } } } 「あれ??大きさを考慮して敷き詰めるなら100:100:100:100:100 = 1:1:1:1:1だから等間隔に敷き詰められるんじゃないの?」 調べてみると どうやらfillProportionallyが比の参考にするのはframeのsizeではなく、intrinsicContentSizeらしい。当たり前といえば当たり前なのかも。 「なるほど。じゃあintrinsicContentSizeを100pt×100ptにしてみよ」 色と大きさを指定できるUIViewを作成 class ColorView: UIView { var size: CGSize init(color: UIColor, size: CGSize) { self.size = size super.init(frame: CGRect()) backgroundColor = color } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override var intrinsicContentSize: CGSize { return CGSize(width: size.width, height: size.height) } } これを水平方向の画面いっぱいに広がるStackViewに入れる class View: UIView { let stackView = UIStackView() let redView = ColorView(color: .red, size: CGSize(width: 100, height: 100)) let orangeView = ColorView(color: .orange, size: CGSize(width: 100, height: 100)) let yellowView = ColorView(color: .yellow, size: CGSize(width: 100, height: 100)) let greenView = ColorView(color: .green, size: CGSize(width: 100, height: 100)) let blueView = ColorView(color: .blue, size: CGSize(width: 100, height: 100)) override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white setupStackView() setupColorViews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupStackView() { stackView.backgroundColor = .white stackView.axis = .horizontal stackView.alignment = .fill stackView.distribution = .fillProportionally addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor), stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), stackView.widthAnchor.constraint(equalTo: self.widthAnchor) ]) } private func setupColorViews() { let colorViews: [UIView] = [redView,orangeView,yellowView,greenView,blueView] colorViews.forEach { view in stackView.addArrangedSubview(view) } } } 「これでできるはず...」 PlaygroundPage.current.liveView = View() 「おーできた」 fillProportionallyらしいコーディングをしてみる 「widthの実際の値をもとにした比に基づいてwidthが定まるのがfillProportionallyだった」 let redView = ColorView(color: .red, size: CGSize(width: 1, height: 100)) let orangeView = ColorView(color: .orange, size: CGSize(width: 2, height: 100)) let yellowView = ColorView(color: .yellow, size: CGSize(width: 3, height: 100)) let greenView = ColorView(color: .green, size: CGSize(width: 4, height: 100)) let blueView = ColorView(color: .blue, size: CGSize(width: 5, height: 100)) なら、これは1:2:3:4:5になるはず 「おー、なってるやん。fillPortionally完全に理解できたわ!」 ソースコード Playgrounds上でコピペで動きます。 import PlaygroundSupport import UIKit class ColorView: UIView { var size: CGSize init(color: UIColor, size: CGSize) { self.size = size super.init(frame: CGRect()) backgroundColor = color } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override var intrinsicContentSize: CGSize { return CGSize(width: size.width, height: size.height) } } class View: UIView { let stackView = UIStackView() let redView = ColorView(color: .red, size: CGSize(width: 1, height: 100)) let orangeView = ColorView(color: .orange, size: CGSize(width: 2, height: 100)) let yellowView = ColorView(color: .yellow, size: CGSize(width: 3, height: 100)) let greenView = ColorView(color: .green, size: CGSize(width: 4, height: 100)) let blueView = ColorView(color: .blue, size: CGSize(width: 5, height: 100)) override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white setupStackView() setupColorViews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupStackView() { stackView.backgroundColor = .white stackView.axis = .horizontal stackView.alignment = .fill stackView.distribution = .fillProportionally addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor), stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), stackView.widthAnchor.constraint(equalTo: self.widthAnchor) ]) } private func setupColorViews() { let colorViews: [UIView] = [redView,orangeView,yellowView,greenView,blueView] colorViews.forEach { view in stackView.addArrangedSubview(view) } } } PlaygroundPage.current.liveView = View()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

swiftでボタンを押された時効果音を流す

AVFoundationというフレームワークがあるみたいね 以下appleサイト https://developer.apple.com/documentation/avfoundation/ import AVFoundation var player: AVAudioPlayer! func playSound(soundName: String?) { let url = Bundle.main.url(forResource: soundName, withExtension: "wav") player = try! AVAudioPlayer(contentsOf: url!) player.play() } forResourceに名前 withExtensionに拡張子 を入れると音が鳴るよ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

swiftでカウントダウンタイマーを作る

swiftでカウントダウンタイマーを作るテンプレです var secondsRemaining = 60 var timer = Timer() timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true) } @objc func updateCounter() { //example functionality if secondsRemaining > 0 { print("\(secondsRemaining) seconds to the end of the world") secondsRemaining -= 1 } } timeIntervalというのが測る間隔値みたい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コードでUIScrollViewサンプル作成

バージョン ・Xcode12.4 ・Swift5 概要 コードでUIScrollViewのサンプルを作成した備忘録 コード test.swift import UIKit class ViewController: UIViewController { // インスタンス化 let outView = UIView() let scrollView = UIScrollView() let inView = UIView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // 背景色の決定 scrollView.backgroundColor = UIColor.black inView.backgroundColor = UIColor.blue view.backgroundColor = UIColor.systemBlue // かくviewに子要素として追加 scrollView.addSubview(inView) view.addSubview(scrollView) // scrollViewの制約の設定 scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true // inViewの制約の設定 // inView:AutoLayoutで使用したContainerViewに該当 // Autosizingという仕組みをAutoLayoutに変換する設定するフラグ:falseでAutoLayoutを有効化 inView.translatesAutoresizingMaskIntoConstraints = false // 横スクロールにするため、高さ:scrollViewと同一、幅:2000.0に設定 inView.widthAnchor.constraint(equalToConstant: 2000.0).isActive = true inView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true inView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true inView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true inView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true inView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true   } } 参考にさせて頂いた記事 コードでUIScrollView(とその子どもたち)をAutoLayout配置 [Xcode11] UIScrollViewとAutolayoutのベストプラクティス
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ScrollViewについての備忘録

バージョン ・Xcode 12.4 ・Swift5 概要 ScrollViewについて色々試したのでその備忘録 やり方は[Xcode11] UIScrollViewとAutolayoutのベストプラクティスを参照。 ContainerViewを以下のように条件を変えてサンプルの作成 1.Width:ScrollViewと同一、Height:2000 2.Width:2000、Height:ScrollViewと同一 3.Width:2000、Height:2000 1 2 3 実機の画像 各設定に対するイメージ ScrollView:スクロール操作ができる場所。ScrollViewの大きさの覗き窓を設定してContainerViewを切り取って見ている。 ContainerView:Viewとは別のレイヤーでScrollViewの上にある。大きさはViewの大きさに縛られない。 参考にさせて頂いた記事 [Xcode11] UIScrollViewとAutolayoutのベストプラクティス
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む