錯誤回顧

影片中 0:03 開始可看到焦點發生了錯誤定位

影片中 0:03 開始可看到焦點發生了錯誤定位

代碼

    @ViewBuilder func ListView() -> some View {
        CocoaList(data.epsList) { ep in

            UniversalEpView(ep: ep)
                .frame(width: 1120)
                .fixedSize(horizontal: false, vertical: true)
                .id(ep.id)
                .focused($focusedField, equals: .equalsID(ep.id))

            if data.epsList.last == ep && data.epsList.count > 1 {
                BackTopBar()
                    .padding(.top, 20)
            }
        }
        .alwaysBounceVertical(true)
        .introspectTableView { tableView in
            self.tableView = tableView
            tableView.delegate = delegateHandler
            tableView.allowsFocus = false
            tableView.allowsSelection = true
            tableView.isPrefetchingEnabled = true
            tableView.rowHeight = UITableView.automaticDimension
            tableView.estimatedRowHeight = 108
        }
    }

在源代碼中,我使用了 CocoaList(基於 UITableView 的封裝)來實現播放列表的 UI。

然而,在這份代碼上,SwiftUI 並不會真實滾動這個 UITableView。

圖片 1:展示 CocoaList 的焦點預測

圖片 1:展示 CocoaList 的焦點預測

圖片 2:焦點預測在 CELL 高度不一致如何工作。

圖片 2:焦點預測在 CELL 高度不一致如何工作。

然而,在這樣編寫的 CocoaList 會一直使用這樣的列表出現在第一屏幕(圖片1)進行後續的焦點預測*。所以,在後續高度不一致的 CELL 上,那麼就會出現焦點對齊錯誤的問題。

*** 焦點預測**:我猜測 SwiftUI 對 UITableView (List) 實現的一種優化手段。 在 os15 版本,List 的背後實現是 UITableView。 在 os16+ 版本,List 的背後實現是 UICollectionView。

解決辦法

為了解決這個問題,我們有兩個方法。

  1. 更新到 xcode 16 並重新編譯 app。(我不太清楚這是否真實的辦法,不過此 Bug 目前無法重現在我經過 xcode 16 編譯的 app 版本下出現。)
  2. 使用 UITableView 裡面的 allowsFocus 功能來接管 SwiftUI 的焦點管理。