iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

next/routerの関数メモ

本日は、next/routerの関数についての軽いメモです🏃🏻‍♂️

関数たち

push

任意の画面に遷移するために使用します。next/linkによる実装が不十分な時などに使用できます。

router.push(url, as, options)

replace

機能的にはpushと同じですが、replaceは遷移時、ブラウザの履歴スタックに追加されません。

router.replace(url, as, options)

prefetch

次の画面の表示を高速化するために、プリフェッチします。ちなみに、next/linkを使っている場合は、プリフェッチが自動的に行われているそうです.

router.prefetch(url, as)

back

一つ前の履歴スタックに戻ります。ブラウザで戻るボタンを押したのと同じ挙動です。

import { useRouter } from 'next/router'

export default function Page() {
  const router = useRouter()

  return (
    <button type="button" onClick={() => router.back()}>
      Click here to go back
    </button>
  )
}

reload

現在のページをリロードします。ブラウザの更新ボタンを押したのと同じ挙動です。

import { useRouter } from 'next/router'

export default function Page() {
  const router = useRouter()

  return (
    <button type="button" onClick={() => router.reload()}>
      Click here to reload
    </button>
  )
}

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

履歴スタックについて少し調べた

Webブラウザの履歴スタック??っとなったので軽くメモ🔰

履歴スタックとは?

ユーザが訪れたページなどをブラウザのウィンドやタブごとに管理するもののことを指します。 また、macなどでは⌘ + 左右矢印などで、ページの前後に移動することができますが、この場合は履歴スタック自体が変更されるのではなく、履歴スタックないの現在位置が変わっているらしいです。

履歴スタックを操作するには?

History APIというものを使って履歴スタックを操作することができるそうです。

https://developer.mozilla.org/ja/docs/Web/API/History_API/Working_with_the_History_API

History APIは触る機会があったらまた記事にしようとおもいます🏃‍♂️ てな感じで本日は以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【TypeScript】返り値を型としてあつかう

下記のような関数の、返り値の型をつくるためのメモです🏃‍♂️

const hoge profile = () => {
  return {
    name: "Yamato",
    age: 23
  }
}

結論

ReturnTypeというものを使って、返り値を型に変換することができるようでした。

type Profile = ReturnType<typeof profile>

ちなみに、このReturnTypeはTypeScriptのUtility Typesというものの一種らしくて、TypeScriptが提供する便利な機能群の一つです。 Utility Typesについては、また他の記事で深ぼっていきたいとおもいます🏃‍♂️

てな感じで本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

AutoLayoutでtargetの比率で高さを計算

本日は初学者向けに、targetとなるViewのサイズに応じて、サイズを計算するAutoLayoutのメソッドを紹介します🏃‍♂️

結論

constraint(equalTo:, multiplier:) で下記のように設定することができます。multiplierにはequalToでしていしたサイズに対する割合を設定します。

view.heightAnchor.constraint(equalTo: target.heightAnchor, multiplier: 0.5).isActive = true

てな感じで本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Fatal: supplied identifiers are not unique.' 対処法

UICollectionViewDiffableDataSourceをつかっていた際にタイトルのエラーが発生したので、対処法をかるくメモ🔰

今回エラーが発生したのは、セクションの情報を追加するときの処理です。

        var snapshot = dataSource.snapshot()
        snapshot.appendSections(newSections)
        newSections.forEach {
            switch $0 {
            case .largeItem(let item, _):
                snapshot.appendItems([item], toSection: $0)
            case .smallItems(let items, _):
                snapshot.appendItems(items, toSection: $0)
            }
        }
        dataSource.apply(snapshot, animatingDifferences: false)

結論

データをリフレッシュするのではなく、追加する時はsnapshot.appendSections(newSections)で、差分のデータだけ含めるようにしましょう。DifferenceKitとかの要領でデータを全て追加してしまっていたので、同じhashvalueを持つデータがsnapshotで重複してしまい今回のエラーが発生していました👀

ちなみに、リフレッシュする時はsnapshot.deleteAllItems()してから、データ追加するとうまくいきます。

てな感じ本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【Swift】UICompositionalLayout + Diffable Data Source 時の再描画処理

再描画時にcollectionViewLayoutを入れ替えて、dataSource.apply(snapshot, animatingDifferences: false)なんてことをしていたが、なんかデータのリフレッシュタイミングでIndex out of rangeになると思ったら更新の仕方が大きく勘違いしていたので軽くメモ✍️ (細かい内容は別途記事にしようとおもいます🏃‍♂️)

結論

UICompositionalLayout + Diffable Data Sourceの場合は、基本的にsnapshotを更新すればよかった。つまり、collectionViewLayoutは下記のように元データを参照させるようにして

        collectionView.collectionViewLayout = UICollectionViewCompositionalLayout {[unowned self] section, _ in
            switch viewModel.sections.value[section] {
            case .largeItem(let item, let section):
                return layoutGenerator.largeLayoutSection(item: item, isFirstItem: section == 0)
            case .smallItems(let items, _):
                return layoutGenerator.itemsLayoutSection(items: items)
            }
        }

再描画時には、dataSource.apply(snapshot, animatingDifferences: false)を実行すればいいということです🛠

let snapshot = dataSource.snapshot()
// TODO: snapshot更新処理
dataSource.apply(snapshot, animatingDifferences: false)

てな感じで本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog