現在作業しているアプリケーションには、ネストされたコレクションビューの設定があります。外側のコレクションビューには、垂直方向にスクロール可能な大きなセルが含まれています。各セルには、小さなセルを含む別のコレクションビューが含まれています(サブコレクションビューのレイアウトが異なるため、大きなセルを含むネストされたコレクションビューにVoiceOverでアクセスできるようにする
視覚的にはうまくいきますが、Voice Overで問題が発生しました。最初の子コレクションビューの最後のアイテム(つまり、外側のコレクションビューの最初のセルの最後のアイテム)に到達すると、スワイプで次のアイテムを選択できません。代わりに、iOSは最後の項目に達したかのように音を出します。
3本の指でスワイプして下にスクロールし、次の要素を選択することはできますが、これは明らかに必要ではありません。最後の要素を選択し、逆の順序でバックアップすることは、意図した通りに機能します。
この問題は、(外部コレクションビューの)1つのセルのみが最初に表示されている場合にのみ発生すると考えられます。複数のセルが表示されている場合、すべてが機能します。しかし、レイアウトを完全に変更するので、外側のセルのサイズを変更することはできません。
問題を示すサンプルビューコントローラを作成しました。プロジェクトの2つのコレクションビューは、セルのサイズを除いて同じです。小さなセルを含む最初のコレクションビューは期待通りに機能します。次のセルを選択するためにスワイプすると、最後に表示されたセルが選択されたときにiOSがさらにビープ音を鳴らします。
だから、私の質問は:
- がどのように私は2番目のコレクションビューは最初のもののように振る舞うことができますか?
- 水平スワイプでアクセスできる2番目のコレクションビューでセルをさらに下に移動するにはどうすればよいですか?私がこれまで試みられてきた
ソリューション:
- 一つのSOポストは、ネストされたコレクションビューのラッパービューを作成示唆しています。これは違いがないようです。
- コレクションビューのカスタムサブクラスでUIAccessibilityContainerプロトコルを自分自身で実装しようとしました。これは奇妙な方法でスクロールしているように見えます。
- 配置「レイアウト変更」それは(それがない)ことができますかどうかを確認するために、ランダムな場所で通知を
編集:問題を実証のViewControllerの 全コード:
class ViewController: UIViewController, UICollectionViewDataSource {
let outerCollectionView = UICollectionView(frame: CGRect(x: 0, y: 40, width: 320, height: 250), collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
outerCollectionView.backgroundColor = .blue
(outerCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = CGSize(width: 250, height: 300)
outerCollectionView.register(OuterCell.self, forCellWithReuseIdentifier: "outerCell")
view.addSubview(outerCollectionView)
outerCollectionView.dataSource = self
}
func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 }
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 4 }
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "outerCell", for: indexPath) as! OuterCell
cell.outerIndex = indexPath.row + 1
return cell
}
}
class OuterCell: UICollectionViewCell, UICollectionViewDataSource {
var innerCollectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 300, height: 500), collectionViewLayout: UICollectionViewFlowLayout())
var outerIndex: Int = 0
override init(frame: CGRect) {
super.init(frame: frame)
(innerCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = CGSize(width: 140, height: 80)
innerCollectionView.backgroundColor = .yellow
innerCollectionView.register(InnerCell.self, forCellWithReuseIdentifier: "innerCell")
contentView.addSubview(innerCollectionView)
innerCollectionView.dataSource = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("unused")
}
func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 }
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 3 }
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "innerCell", for: indexPath) as! InnerCell
cell.label.text = "Cell \(outerIndex)/\(indexPath.item+1)"
return cell
}
}
class InnerCell: UICollectionViewCell {
let label = UILabel(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 30)))
override init(frame: CGRect) {
super.init(frame: frame)
contentView.backgroundColor = .white
contentView.addSubview(label)
}
required init?(coder aDecoder: NSCoder) {
fatalError("unused")
}
}
編集:問題を示す動画はhttps://vimeo.com/229249955です(ここに少し説明が追加されています)。
ここに外部リソースの代わりにコードを掲載できますか? –
私はView Controllerのコードを投稿することができましたが、ストーリーボードなしではあまり役に立ちません。とにかく私はそれを掲示すべきですか? – jasamer
Stack Overflowで投稿するときは、[最小、完全で検証可能な例](https://stackoverflow.com/help/mcve)を投稿してみてください –