0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Fscalendarでreloaddata()時に画面が点滅するバグ

Posted at

このバグの改修に丸二日ほど費やしたので備忘録として記事にします。
まず最初に環境としては、SwiftUIとFscalendarを使ってアプリの開発をしていました。

バグの詳細

バグの内容はFscalendarで日付の選択をしたときに、選択した日付以外の日付がフラッシュするといった内容のものです。
スクリーンショット 2023-11-04 20.01.23.png

解決策

原因はupdateUIView()の中でreloadData()が複数回実行されていることでした。
これだけだとソースコードによって状況が違うと思いますので、私のパターンのソースコードの概要を以下に示します。

qiita.swift
struct CalendarDispView : UIViewRepresentable {
    
    func makeUIView(context: Context) -> FSCalendar {
        typealias UIViewType = FSCalendar
        let fsCalendar = FSCalendar()
        
        fsCalendar.delegate = context.coordinator
        fsCalendar.dataSource = context.coordinator
        
        return fsCalendar
    }
    
    func updateUIView(_ uiView: FSCalendar, context: Context) {
        context.coordinator.updateCalendar(uiView as FSCalendar, with: selectedDate)
        
        // 該当箇所 ここが原因でフラッシュが発生していた
        uiView.reloadData()
    }
    
    func makeCoordinator() -> Coordinator{
        return Coordinator(self)
    }
    
    class Coordinator: NSObject, FSCalendarDelegate, FSCalendarDataSource {
        var parent:CalendarDispView
        
        init(_ parent:CalendarDispView){
            self.parent = parent
        }
        
        func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
            parent.selectedDate = date
        }
    }
}

SwiftUIを使用して、Fscalendarを使用すると大体このようなコードになると思うのですが、私の場合は該当箇所でreloadData()を使っていました。

解決策は、reloadData()を必要な時のみ行うことです。

qiita.swift
    func updateUIView(_ uiView: FSCalendar, context: Context) {
        context.coordinator.updateCalendar(uiView as FSCalendar, with: selectedDate)
        // フラグがtrueであれば、reloadData()が実行されない
        if updateCheck.updateFlag { return }
        uiView.reloadData()
    }

reloadData()が複数回実行されることがなくなり、画面のフラッシュが発生しなくなります。
余談ですが、updateUIView()は構造体のプロパティが更新されるたびに呼び出されるため、reloadData()はFscalendarのイベントマークを更新するために使用していました。

わかりにくい文章ですが、ここまでお読みいただきありがとうございました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?